1 
   2 /******************************************************************************
   3  *
   4  * Module Name: exstoren - AML Interpreter object store support,
   5  *                        Store to Node (namespace object)
   6  *
   7  *****************************************************************************/
   8 
   9 /*
  10  * Copyright (C) 2000 - 2011, Intel Corp.
  11  * All rights reserved.
  12  *
  13  * Redistribution and use in source and binary forms, with or without
  14  * modification, are permitted provided that the following conditions
  15  * are met:
  16  * 1. Redistributions of source code must retain the above copyright
  17  *    notice, this list of conditions, and the following disclaimer,
  18  *    without modification.
  19  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  20  *    substantially similar to the "NO WARRANTY" disclaimer below
  21  *    ("Disclaimer") and any redistribution must be conditioned upon
  22  *    including a substantially similar Disclaimer requirement for further
  23  *    binary redistribution.
  24  * 3. Neither the names of the above-listed copyright holders nor the names
  25  *    of any contributors may be used to endorse or promote products derived
  26  *    from this software without specific prior written permission.
  27  *
  28  * Alternatively, this software may be distributed under the terms of the
  29  * GNU General Public License ("GPL") version 2 as published by the Free
  30  * Software Foundation.
  31  *
  32  * NO WARRANTY
  33  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  34  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  35  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  36  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  37  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  38  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  39  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  40  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  41  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  42  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  43  * POSSIBILITY OF SUCH DAMAGES.
  44  */
  45 
  46 #define __EXSTOREN_C__
  47 
  48 #include "acpi.h"
  49 #include "accommon.h"
  50 #include "acinterp.h"
  51 #include "amlcode.h"
  52 
  53 
  54 #define _COMPONENT          ACPI_EXECUTER
  55         ACPI_MODULE_NAME    ("exstoren")
  56 
  57 
  58 /*******************************************************************************
  59  *
  60  * FUNCTION:    AcpiExResolveObject
  61  *
  62  * PARAMETERS:  SourceDescPtr       - Pointer to the source object
  63  *              TargetType          - Current type of the target
  64  *              WalkState           - Current walk state
  65  *
  66  * RETURN:      Status, resolved object in SourceDescPtr.
  67  *
  68  * DESCRIPTION: Resolve an object.  If the object is a reference, dereference
  69  *              it and return the actual object in the SourceDescPtr.
  70  *
  71  ******************************************************************************/
  72 
  73 ACPI_STATUS
  74 AcpiExResolveObject (
  75     ACPI_OPERAND_OBJECT     **SourceDescPtr,
  76     ACPI_OBJECT_TYPE        TargetType,
  77     ACPI_WALK_STATE         *WalkState)
  78 {
  79     ACPI_OPERAND_OBJECT     *SourceDesc = *SourceDescPtr;
  80     ACPI_STATUS             Status = AE_OK;
  81 
  82 
  83     ACPI_FUNCTION_TRACE (ExResolveObject);
  84 
  85 
  86     /* Ensure we have a Target that can be stored to */
  87 
  88     switch (TargetType)
  89     {
  90     case ACPI_TYPE_BUFFER_FIELD:
  91     case ACPI_TYPE_LOCAL_REGION_FIELD:
  92     case ACPI_TYPE_LOCAL_BANK_FIELD:
  93     case ACPI_TYPE_LOCAL_INDEX_FIELD:
  94         /*
  95          * These cases all require only Integers or values that
  96          * can be converted to Integers (Strings or Buffers)
  97          */
  98 
  99     case ACPI_TYPE_INTEGER:
 100     case ACPI_TYPE_STRING:
 101     case ACPI_TYPE_BUFFER:
 102 
 103         /*
 104          * Stores into a Field/Region or into a Integer/Buffer/String
 105          * are all essentially the same.  This case handles the
 106          * "interchangeable" types Integer, String, and Buffer.
 107          */
 108         if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
 109         {
 110             /* Resolve a reference object first */
 111 
 112             Status = AcpiExResolveToValue (SourceDescPtr, WalkState);
 113             if (ACPI_FAILURE (Status))
 114             {
 115                 break;
 116             }
 117         }
 118 
 119         /* For CopyObject, no further validation necessary */
 120 
 121         if (WalkState->Opcode == AML_COPY_OP)
 122         {
 123             break;
 124         }
 125 
 126         /* Must have a Integer, Buffer, or String */
 127 
 128         if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER)    &&
 129             (SourceDesc->Common.Type != ACPI_TYPE_BUFFER)     &&
 130             (SourceDesc->Common.Type != ACPI_TYPE_STRING)     &&
 131             !((SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
 132                     (SourceDesc->Reference.Class== ACPI_REFCLASS_TABLE)))
 133         {
 134             /* Conversion successful but still not a valid type */
 135 
 136             ACPI_ERROR ((AE_INFO,
 137                 "Cannot assign type %s to %s (must be type Int/Str/Buf)",
 138                 AcpiUtGetObjectTypeName (SourceDesc),
 139                 AcpiUtGetTypeName (TargetType)));
 140             Status = AE_AML_OPERAND_TYPE;
 141         }
 142         break;
 143 
 144 
 145     case ACPI_TYPE_LOCAL_ALIAS:
 146     case ACPI_TYPE_LOCAL_METHOD_ALIAS:
 147 
 148         /*
 149          * All aliases should have been resolved earlier, during the
 150          * operand resolution phase.
 151          */
 152         ACPI_ERROR ((AE_INFO, "Store into an unresolved Alias object"));
 153         Status = AE_AML_INTERNAL;
 154         break;
 155 
 156 
 157     case ACPI_TYPE_PACKAGE:
 158     default:
 159 
 160         /*
 161          * All other types than Alias and the various Fields come here,
 162          * including the untyped case - ACPI_TYPE_ANY.
 163          */
 164         break;
 165     }
 166 
 167     return_ACPI_STATUS (Status);
 168 }
 169 
 170 
 171 /*******************************************************************************
 172  *
 173  * FUNCTION:    AcpiExStoreObjectToObject
 174  *
 175  * PARAMETERS:  SourceDesc          - Object to store
 176  *              DestDesc            - Object to receive a copy of the source
 177  *              NewDesc             - New object if DestDesc is obsoleted
 178  *              WalkState           - Current walk state
 179  *
 180  * RETURN:      Status
 181  *
 182  * DESCRIPTION: "Store" an object to another object.  This may include
 183  *              converting the source type to the target type (implicit
 184  *              conversion), and a copy of the value of the source to
 185  *              the target.
 186  *
 187  *              The Assignment of an object to another (not named) object
 188  *              is handled here.
 189  *              The Source passed in will replace the current value (if any)
 190  *              with the input value.
 191  *
 192  *              When storing into an object the data is converted to the
 193  *              target object type then stored in the object.  This means
 194  *              that the target object type (for an initialized target) will
 195  *              not be changed by a store operation.
 196  *
 197  *              This module allows destination types of Number, String,
 198  *              Buffer, and Package.
 199  *
 200  *              Assumes parameters are already validated.  NOTE: SourceDesc
 201  *              resolution (from a reference object) must be performed by
 202  *              the caller if necessary.
 203  *
 204  ******************************************************************************/
 205 
 206 ACPI_STATUS
 207 AcpiExStoreObjectToObject (
 208     ACPI_OPERAND_OBJECT     *SourceDesc,
 209     ACPI_OPERAND_OBJECT     *DestDesc,
 210     ACPI_OPERAND_OBJECT     **NewDesc,
 211     ACPI_WALK_STATE         *WalkState)
 212 {
 213     ACPI_OPERAND_OBJECT     *ActualSrcDesc;
 214     ACPI_STATUS             Status = AE_OK;
 215 
 216 
 217     ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToObject, SourceDesc);
 218 
 219 
 220     ActualSrcDesc = SourceDesc;
 221     if (!DestDesc)
 222     {
 223         /*
 224          * There is no destination object (An uninitialized node or
 225          * package element), so we can simply copy the source object
 226          * creating a new destination object
 227          */
 228         Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, NewDesc, WalkState);
 229         return_ACPI_STATUS (Status);
 230     }
 231 
 232     if (SourceDesc->Common.Type != DestDesc->Common.Type)
 233     {
 234         /*
 235          * The source type does not match the type of the destination.
 236          * Perform the "implicit conversion" of the source to the current type
 237          * of the target as per the ACPI specification.
 238          *
 239          * If no conversion performed, ActualSrcDesc = SourceDesc.
 240          * Otherwise, ActualSrcDesc is a temporary object to hold the
 241          * converted object.
 242          */
 243         Status = AcpiExConvertToTargetType (DestDesc->Common.Type,
 244                         SourceDesc, &ActualSrcDesc, WalkState);
 245         if (ACPI_FAILURE (Status))
 246         {
 247             return_ACPI_STATUS (Status);
 248         }
 249 
 250         if (SourceDesc == ActualSrcDesc)
 251         {
 252             /*
 253              * No conversion was performed. Return the SourceDesc as the
 254              * new object.
 255              */
 256             *NewDesc = SourceDesc;
 257             return_ACPI_STATUS (AE_OK);
 258         }
 259     }
 260 
 261     /*
 262      * We now have two objects of identical types, and we can perform a
 263      * copy of the *value* of the source object.
 264      */
 265     switch (DestDesc->Common.Type)
 266     {
 267     case ACPI_TYPE_INTEGER:
 268 
 269         DestDesc->Integer.Value = ActualSrcDesc->Integer.Value;
 270 
 271         /* Truncate value if we are executing from a 32-bit ACPI table */
 272 
 273         AcpiExTruncateFor32bitTable (DestDesc);
 274         break;
 275 
 276     case ACPI_TYPE_STRING:
 277 
 278         Status = AcpiExStoreStringToString (ActualSrcDesc, DestDesc);
 279         break;
 280 
 281     case ACPI_TYPE_BUFFER:
 282 
 283         Status = AcpiExStoreBufferToBuffer (ActualSrcDesc, DestDesc);
 284         break;
 285 
 286     case ACPI_TYPE_PACKAGE:
 287 
 288         Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, &DestDesc,
 289                     WalkState);
 290         break;
 291 
 292     default:
 293         /*
 294          * All other types come here.
 295          */
 296         ACPI_WARNING ((AE_INFO, "Store into type %s not implemented",
 297             AcpiUtGetObjectTypeName (DestDesc)));
 298 
 299         Status = AE_NOT_IMPLEMENTED;
 300         break;
 301     }
 302 
 303     if (ActualSrcDesc != SourceDesc)
 304     {
 305         /* Delete the intermediate (temporary) source object */
 306 
 307         AcpiUtRemoveReference (ActualSrcDesc);
 308     }
 309 
 310     *NewDesc = DestDesc;
 311     return_ACPI_STATUS (Status);
 312 }
 313 
 314