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 - 2012, 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 <contrib/dev/acpica/include/acpi.h> 48 #include <contrib/dev/acpica/include/accommon.h> 49 #include <contrib/dev/acpica/include/acinterp.h> 50 #include <contrib/dev/acpica/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 98 case ACPI_TYPE_INTEGER: 99 case ACPI_TYPE_STRING: 100 case ACPI_TYPE_BUFFER: 101 102 /* 103 * Stores into a Field/Region or into a Integer/Buffer/String 104 * are all essentially the same. This case handles the 105 * "interchangeable" types Integer, String, and Buffer. 106 */ 107 if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) 108 { 109 /* Resolve a reference object first */ 110 111 Status = AcpiExResolveToValue (SourceDescPtr, WalkState); 112 if (ACPI_FAILURE (Status)) 113 { 114 break; 115 } 116 } 117 118 /* For CopyObject, no further validation necessary */ 119 120 if (WalkState->Opcode == AML_COPY_OP) 121 { 122 break; 123 } 124 125 /* Must have a Integer, Buffer, or String */ 126 127 if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER) && 128 (SourceDesc->Common.Type != ACPI_TYPE_BUFFER) && 129 (SourceDesc->Common.Type != ACPI_TYPE_STRING) && 130 !((SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 131 (SourceDesc->Reference.Class== ACPI_REFCLASS_TABLE))) 132 { 133 /* Conversion successful but still not a valid type */ 134 135 ACPI_ERROR ((AE_INFO, 136 "Cannot assign type %s to %s (must be type Int/Str/Buf)", 137 AcpiUtGetObjectTypeName (SourceDesc), 138 AcpiUtGetTypeName (TargetType))); 139 Status = AE_AML_OPERAND_TYPE; 140 } 141 break; 142 143 144 case ACPI_TYPE_LOCAL_ALIAS: 145 case ACPI_TYPE_LOCAL_METHOD_ALIAS: 146 147 /* 148 * All aliases should have been resolved earlier, during the 149 * operand resolution phase. 150 */ 151 ACPI_ERROR ((AE_INFO, "Store into an unresolved Alias object")); 152 Status = AE_AML_INTERNAL; 153 break; 154 155 156 case ACPI_TYPE_PACKAGE: 157 default: 158 159 /* 160 * All other types than Alias and the various Fields come here, 161 * including the untyped case - ACPI_TYPE_ANY. 162 */ 163 break; 164 } 165 166 return_ACPI_STATUS (Status); 167 } 168 169 170 /******************************************************************************* 171 * 172 * FUNCTION: AcpiExStoreObjectToObject 173 * 174 * PARAMETERS: SourceDesc - Object to store 175 * DestDesc - Object to receive a copy of the source 176 * NewDesc - New object if DestDesc is obsoleted 177 * WalkState - Current walk state 178 * 179 * RETURN: Status 180 * 181 * DESCRIPTION: "Store" an object to another object. This may include 182 * converting the source type to the target type (implicit 183 * conversion), and a copy of the value of the source to 184 * the target. 185 * 186 * The Assignment of an object to another (not named) object 187 * is handled here. 188 * The Source passed in will replace the current value (if any) 189 * with the input value. 190 * 191 * When storing into an object the data is converted to the 192 * target object type then stored in the object. This means 193 * that the target object type (for an initialized target) will 194 * not be changed by a store operation. 195 * 196 * This module allows destination types of Number, String, 197 * Buffer, and Package. 198 * 199 * Assumes parameters are already validated. NOTE: SourceDesc 200 * resolution (from a reference object) must be performed by 201 * the caller if necessary. 202 * 203 ******************************************************************************/ 204 205 ACPI_STATUS 206 AcpiExStoreObjectToObject ( 207 ACPI_OPERAND_OBJECT *SourceDesc, 208 ACPI_OPERAND_OBJECT *DestDesc, 209 ACPI_OPERAND_OBJECT **NewDesc, 210 ACPI_WALK_STATE *WalkState) 211 { 212 ACPI_OPERAND_OBJECT *ActualSrcDesc; 213 ACPI_STATUS Status = AE_OK; 214 215 216 ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToObject, SourceDesc); 217 218 219 ActualSrcDesc = SourceDesc; 220 if (!DestDesc) 221 { 222 /* 223 * There is no destination object (An uninitialized node or 224 * package element), so we can simply copy the source object 225 * creating a new destination object 226 */ 227 Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, NewDesc, WalkState); 228 return_ACPI_STATUS (Status); 229 } 230 231 if (SourceDesc->Common.Type != DestDesc->Common.Type) 232 { 233 /* 234 * The source type does not match the type of the destination. 235 * Perform the "implicit conversion" of the source to the current type 236 * of the target as per the ACPI specification. 237 * 238 * If no conversion performed, ActualSrcDesc = SourceDesc. 239 * Otherwise, ActualSrcDesc is a temporary object to hold the 240 * converted object. 241 */ 242 Status = AcpiExConvertToTargetType (DestDesc->Common.Type, 243 SourceDesc, &ActualSrcDesc, WalkState); 244 if (ACPI_FAILURE (Status)) 245 { 246 return_ACPI_STATUS (Status); 247 } 248 249 if (SourceDesc == ActualSrcDesc) 250 { 251 /* 252 * No conversion was performed. Return the SourceDesc as the 253 * new object. 254 */ 255 *NewDesc = SourceDesc; 256 return_ACPI_STATUS (AE_OK); 257 } 258 } 259 260 /* 261 * We now have two objects of identical types, and we can perform a 262 * copy of the *value* of the source object. 263 */ 264 switch (DestDesc->Common.Type) 265 { 266 case ACPI_TYPE_INTEGER: 267 268 DestDesc->Integer.Value = ActualSrcDesc->Integer.Value; 269 270 /* Truncate value if we are executing from a 32-bit ACPI table */ 271 272 AcpiExTruncateFor32bitTable (DestDesc); 273 break; 274 275 case ACPI_TYPE_STRING: 276 277 Status = AcpiExStoreStringToString (ActualSrcDesc, DestDesc); 278 break; 279 280 case ACPI_TYPE_BUFFER: 281 282 Status = AcpiExStoreBufferToBuffer (ActualSrcDesc, DestDesc); 283 break; 284 285 case ACPI_TYPE_PACKAGE: 286 287 Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, &DestDesc, 288 WalkState); 289 break; 290 291 default: 292 /* 293 * All other types come here. 294 */ 295 ACPI_WARNING ((AE_INFO, "Store into type %s not implemented", 296 AcpiUtGetObjectTypeName (DestDesc))); 297 298 Status = AE_NOT_IMPLEMENTED; 299 break; 300 } 301 302 if (ActualSrcDesc != SourceDesc) 303 { 304 /* Delete the intermediate (temporary) source object */ 305 306 AcpiUtRemoveReference (ActualSrcDesc); 307 } 308 309 *NewDesc = DestDesc; 310 return_ACPI_STATUS (Status); 311 } 312