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 - 2017, 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 136 Status = AE_AML_OPERAND_TYPE; 137 } 138 break; 139 140 case ACPI_TYPE_LOCAL_ALIAS: 141 case ACPI_TYPE_LOCAL_METHOD_ALIAS: 142 /* 143 * All aliases should have been resolved earlier, during the 144 * operand resolution phase. 145 */ 146 ACPI_ERROR ((AE_INFO, "Store into an unresolved Alias object")); 147 Status = AE_AML_INTERNAL; 148 break; 149 150 case ACPI_TYPE_PACKAGE: 151 default: 152 /* 153 * All other types than Alias and the various Fields come here, 154 * including the untyped case - ACPI_TYPE_ANY. 155 */ 156 break; 157 } 158 159 return_ACPI_STATUS (Status); 160 } 161 162 163 /******************************************************************************* 164 * 165 * FUNCTION: AcpiExStoreObjectToObject 166 * 167 * PARAMETERS: SourceDesc - Object to store 168 * DestDesc - Object to receive a copy of the source 169 * NewDesc - New object if DestDesc is obsoleted 170 * WalkState - Current walk state 171 * 172 * RETURN: Status 173 * 174 * DESCRIPTION: "Store" an object to another object. This may include 175 * converting the source type to the target type (implicit 176 * conversion), and a copy of the value of the source to 177 * the target. 178 * 179 * The Assignment of an object to another (not named) object 180 * is handled here. 181 * The Source passed in will replace the current value (if any) 182 * with the input value. 183 * 184 * When storing into an object the data is converted to the 185 * target object type then stored in the object. This means 186 * that the target object type (for an initialized target) will 187 * not be changed by a store operation. 188 * 189 * This module allows destination types of Number, String, 190 * Buffer, and Package. 191 * 192 * Assumes parameters are already validated. NOTE: SourceDesc 193 * resolution (from a reference object) must be performed by 194 * the caller if necessary. 195 * 196 ******************************************************************************/ 197 198 ACPI_STATUS 199 AcpiExStoreObjectToObject ( 200 ACPI_OPERAND_OBJECT *SourceDesc, 201 ACPI_OPERAND_OBJECT *DestDesc, 202 ACPI_OPERAND_OBJECT **NewDesc, 203 ACPI_WALK_STATE *WalkState) 204 { 205 ACPI_OPERAND_OBJECT *ActualSrcDesc; 206 ACPI_STATUS Status = AE_OK; 207 208 209 ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToObject, SourceDesc); 210 211 212 ActualSrcDesc = SourceDesc; 213 if (!DestDesc) 214 { 215 /* 216 * There is no destination object (An uninitialized node or 217 * package element), so we can simply copy the source object 218 * creating a new destination object 219 */ 220 Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, NewDesc, WalkState); 221 return_ACPI_STATUS (Status); 222 } 223 224 if (SourceDesc->Common.Type != DestDesc->Common.Type) 225 { 226 /* 227 * The source type does not match the type of the destination. 228 * Perform the "implicit conversion" of the source to the current type 229 * of the target as per the ACPI specification. 230 * 231 * If no conversion performed, ActualSrcDesc = SourceDesc. 232 * Otherwise, ActualSrcDesc is a temporary object to hold the 233 * converted object. 234 */ 235 Status = AcpiExConvertToTargetType (DestDesc->Common.Type, 236 SourceDesc, &ActualSrcDesc, WalkState); 237 if (ACPI_FAILURE (Status)) 238 { 239 return_ACPI_STATUS (Status); 240 } 241 242 if (SourceDesc == ActualSrcDesc) 243 { 244 /* 245 * No conversion was performed. Return the SourceDesc as the 246 * new object. 247 */ 248 *NewDesc = SourceDesc; 249 return_ACPI_STATUS (AE_OK); 250 } 251 } 252 253 /* 254 * We now have two objects of identical types, and we can perform a 255 * copy of the *value* of the source object. 256 */ 257 switch (DestDesc->Common.Type) 258 { 259 case ACPI_TYPE_INTEGER: 260 261 DestDesc->Integer.Value = ActualSrcDesc->Integer.Value; 262 263 /* Truncate value if we are executing from a 32-bit ACPI table */ 264 265 (void) AcpiExTruncateFor32bitTable (DestDesc); 266 break; 267 268 case ACPI_TYPE_STRING: 269 270 Status = AcpiExStoreStringToString (ActualSrcDesc, DestDesc); 271 break; 272 273 case ACPI_TYPE_BUFFER: 274 275 Status = AcpiExStoreBufferToBuffer (ActualSrcDesc, DestDesc); 276 break; 277 278 case ACPI_TYPE_PACKAGE: 279 280 Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, &DestDesc, 281 WalkState); 282 break; 283 284 default: 285 /* 286 * All other types come here. 287 */ 288 ACPI_WARNING ((AE_INFO, "Store into type [%s] not implemented", 289 AcpiUtGetObjectTypeName (DestDesc))); 290 291 Status = AE_NOT_IMPLEMENTED; 292 break; 293 } 294 295 if (ActualSrcDesc != SourceDesc) 296 { 297 /* Delete the intermediate (temporary) source object */ 298 299 AcpiUtRemoveReference (ActualSrcDesc); 300 } 301 302 *NewDesc = DestDesc; 303 return_ACPI_STATUS (Status); 304 } 305