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