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