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