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