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