1 /****************************************************************************** 2 * 3 * Module Name: dsargs - Support for execution of dynamic arguments for static 4 * objects (regions, fields, buffer fields, etc.) 5 * 6 *****************************************************************************/ 7 8 /* 9 * Copyright (C) 2000 - 2011, 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 "acparser.h" 48 #include "amlcode.h" 49 #include "acdispat.h" 50 #include "acnamesp.h" 51 52 #define _COMPONENT ACPI_DISPATCHER 53 ACPI_MODULE_NAME("dsargs") 54 55 /* Local prototypes */ 56 static acpi_status 57 acpi_ds_execute_arguments(struct acpi_namespace_node *node, 58 struct acpi_namespace_node *scope_node, 59 u32 aml_length, u8 *aml_start); 60 61 /******************************************************************************* 62 * 63 * FUNCTION: acpi_ds_execute_arguments 64 * 65 * PARAMETERS: Node - Object NS node 66 * scope_node - Parent NS node 67 * aml_length - Length of executable AML 68 * aml_start - Pointer to the AML 69 * 70 * RETURN: Status. 71 * 72 * DESCRIPTION: Late (deferred) execution of region or field arguments 73 * 74 ******************************************************************************/ 75 76 static acpi_status 77 acpi_ds_execute_arguments(struct acpi_namespace_node *node, 78 struct acpi_namespace_node *scope_node, 79 u32 aml_length, u8 *aml_start) 80 { 81 acpi_status status; 82 union acpi_parse_object *op; 83 struct acpi_walk_state *walk_state; 84 85 ACPI_FUNCTION_TRACE(ds_execute_arguments); 86 87 /* Allocate a new parser op to be the root of the parsed tree */ 88 89 op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP); 90 if (!op) { 91 return_ACPI_STATUS(AE_NO_MEMORY); 92 } 93 94 /* Save the Node for use in acpi_ps_parse_aml */ 95 96 op->common.node = scope_node; 97 98 /* Create and initialize a new parser state */ 99 100 walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL); 101 if (!walk_state) { 102 status = AE_NO_MEMORY; 103 goto cleanup; 104 } 105 106 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, 107 aml_length, NULL, ACPI_IMODE_LOAD_PASS1); 108 if (ACPI_FAILURE(status)) { 109 acpi_ds_delete_walk_state(walk_state); 110 goto cleanup; 111 } 112 113 /* Mark this parse as a deferred opcode */ 114 115 walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP; 116 walk_state->deferred_node = node; 117 118 /* Pass1: Parse the entire declaration */ 119 120 status = acpi_ps_parse_aml(walk_state); 121 if (ACPI_FAILURE(status)) { 122 goto cleanup; 123 } 124 125 /* Get and init the Op created above */ 126 127 op->common.node = node; 128 acpi_ps_delete_parse_tree(op); 129 130 /* Evaluate the deferred arguments */ 131 132 op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP); 133 if (!op) { 134 return_ACPI_STATUS(AE_NO_MEMORY); 135 } 136 137 op->common.node = scope_node; 138 139 /* Create and initialize a new parser state */ 140 141 walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL); 142 if (!walk_state) { 143 status = AE_NO_MEMORY; 144 goto cleanup; 145 } 146 147 /* Execute the opcode and arguments */ 148 149 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, 150 aml_length, NULL, ACPI_IMODE_EXECUTE); 151 if (ACPI_FAILURE(status)) { 152 acpi_ds_delete_walk_state(walk_state); 153 goto cleanup; 154 } 155 156 /* Mark this execution as a deferred opcode */ 157 158 walk_state->deferred_node = node; 159 status = acpi_ps_parse_aml(walk_state); 160 161 cleanup: 162 acpi_ps_delete_parse_tree(op); 163 return_ACPI_STATUS(status); 164 } 165 166 /******************************************************************************* 167 * 168 * FUNCTION: acpi_ds_get_buffer_field_arguments 169 * 170 * PARAMETERS: obj_desc - A valid buffer_field object 171 * 172 * RETURN: Status. 173 * 174 * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late 175 * evaluation of these field attributes. 176 * 177 ******************************************************************************/ 178 179 acpi_status 180 acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc) 181 { 182 union acpi_operand_object *extra_desc; 183 struct acpi_namespace_node *node; 184 acpi_status status; 185 186 ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc); 187 188 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { 189 return_ACPI_STATUS(AE_OK); 190 } 191 192 /* Get the AML pointer (method object) and buffer_field node */ 193 194 extra_desc = acpi_ns_get_secondary_object(obj_desc); 195 node = obj_desc->buffer_field.node; 196 197 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_BUFFER_FIELD, 198 node, NULL)); 199 200 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n", 201 acpi_ut_get_node_name(node))); 202 203 /* Execute the AML code for the term_arg arguments */ 204 205 status = acpi_ds_execute_arguments(node, node->parent, 206 extra_desc->extra.aml_length, 207 extra_desc->extra.aml_start); 208 return_ACPI_STATUS(status); 209 } 210 211 /******************************************************************************* 212 * 213 * FUNCTION: acpi_ds_get_bank_field_arguments 214 * 215 * PARAMETERS: obj_desc - A valid bank_field object 216 * 217 * RETURN: Status. 218 * 219 * DESCRIPTION: Get bank_field bank_value. This implements the late 220 * evaluation of these field attributes. 221 * 222 ******************************************************************************/ 223 224 acpi_status 225 acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc) 226 { 227 union acpi_operand_object *extra_desc; 228 struct acpi_namespace_node *node; 229 acpi_status status; 230 231 ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc); 232 233 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { 234 return_ACPI_STATUS(AE_OK); 235 } 236 237 /* Get the AML pointer (method object) and bank_field node */ 238 239 extra_desc = acpi_ns_get_secondary_object(obj_desc); 240 node = obj_desc->bank_field.node; 241 242 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname 243 (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL)); 244 245 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n", 246 acpi_ut_get_node_name(node))); 247 248 /* Execute the AML code for the term_arg arguments */ 249 250 status = acpi_ds_execute_arguments(node, node->parent, 251 extra_desc->extra.aml_length, 252 extra_desc->extra.aml_start); 253 return_ACPI_STATUS(status); 254 } 255 256 /******************************************************************************* 257 * 258 * FUNCTION: acpi_ds_get_buffer_arguments 259 * 260 * PARAMETERS: obj_desc - A valid Buffer object 261 * 262 * RETURN: Status. 263 * 264 * DESCRIPTION: Get Buffer length and initializer byte list. This implements 265 * the late evaluation of these attributes. 266 * 267 ******************************************************************************/ 268 269 acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc) 270 { 271 struct acpi_namespace_node *node; 272 acpi_status status; 273 274 ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc); 275 276 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { 277 return_ACPI_STATUS(AE_OK); 278 } 279 280 /* Get the Buffer node */ 281 282 node = obj_desc->buffer.node; 283 if (!node) { 284 ACPI_ERROR((AE_INFO, 285 "No pointer back to namespace node in buffer object %p", 286 obj_desc)); 287 return_ACPI_STATUS(AE_AML_INTERNAL); 288 } 289 290 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n")); 291 292 /* Execute the AML code for the term_arg arguments */ 293 294 status = acpi_ds_execute_arguments(node, node, 295 obj_desc->buffer.aml_length, 296 obj_desc->buffer.aml_start); 297 return_ACPI_STATUS(status); 298 } 299 300 /******************************************************************************* 301 * 302 * FUNCTION: acpi_ds_get_package_arguments 303 * 304 * PARAMETERS: obj_desc - A valid Package object 305 * 306 * RETURN: Status. 307 * 308 * DESCRIPTION: Get Package length and initializer byte list. This implements 309 * the late evaluation of these attributes. 310 * 311 ******************************************************************************/ 312 313 acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc) 314 { 315 struct acpi_namespace_node *node; 316 acpi_status status; 317 318 ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc); 319 320 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { 321 return_ACPI_STATUS(AE_OK); 322 } 323 324 /* Get the Package node */ 325 326 node = obj_desc->package.node; 327 if (!node) { 328 ACPI_ERROR((AE_INFO, 329 "No pointer back to namespace node in package %p", 330 obj_desc)); 331 return_ACPI_STATUS(AE_AML_INTERNAL); 332 } 333 334 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n")); 335 336 /* Execute the AML code for the term_arg arguments */ 337 338 status = acpi_ds_execute_arguments(node, node, 339 obj_desc->package.aml_length, 340 obj_desc->package.aml_start); 341 return_ACPI_STATUS(status); 342 } 343 344 /******************************************************************************* 345 * 346 * FUNCTION: acpi_ds_get_region_arguments 347 * 348 * PARAMETERS: obj_desc - A valid region object 349 * 350 * RETURN: Status. 351 * 352 * DESCRIPTION: Get region address and length. This implements the late 353 * evaluation of these region attributes. 354 * 355 ******************************************************************************/ 356 357 acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc) 358 { 359 struct acpi_namespace_node *node; 360 acpi_status status; 361 union acpi_operand_object *extra_desc; 362 363 ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc); 364 365 if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { 366 return_ACPI_STATUS(AE_OK); 367 } 368 369 extra_desc = acpi_ns_get_secondary_object(obj_desc); 370 if (!extra_desc) { 371 return_ACPI_STATUS(AE_NOT_EXIST); 372 } 373 374 /* Get the Region node */ 375 376 node = obj_desc->region.node; 377 378 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname 379 (ACPI_TYPE_REGION, node, NULL)); 380 381 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n", 382 acpi_ut_get_node_name(node), 383 extra_desc->extra.aml_start)); 384 385 /* Execute the argument AML */ 386 387 status = acpi_ds_execute_arguments(node, node->parent, 388 extra_desc->extra.aml_length, 389 extra_desc->extra.aml_start); 390 return_ACPI_STATUS(status); 391 } 392