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