| .. | .. |
|---|
| 14 | 14 | #define _COMPONENT ACPI_NAMESPACE |
|---|
| 15 | 15 | ACPI_MODULE_NAME("nseval") |
|---|
| 16 | 16 | |
|---|
| 17 | | -/* Local prototypes */ |
|---|
| 18 | | -static void |
|---|
| 19 | | -acpi_ns_exec_module_code(union acpi_operand_object *method_obj, |
|---|
| 20 | | - struct acpi_evaluate_info *info); |
|---|
| 21 | | - |
|---|
| 22 | 17 | /******************************************************************************* |
|---|
| 23 | 18 | * |
|---|
| 24 | 19 | * FUNCTION: acpi_ns_evaluate |
|---|
| .. | .. |
|---|
| 44 | 39 | * MUTEX: Locks interpreter |
|---|
| 45 | 40 | * |
|---|
| 46 | 41 | ******************************************************************************/ |
|---|
| 47 | | - |
|---|
| 48 | 42 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) |
|---|
| 49 | 43 | { |
|---|
| 50 | 44 | acpi_status status; |
|---|
| .. | .. |
|---|
| 103 | 97 | if (!info->full_pathname) { |
|---|
| 104 | 98 | return_ACPI_STATUS(AE_NO_MEMORY); |
|---|
| 105 | 99 | } |
|---|
| 100 | + |
|---|
| 101 | + /* Optional object evaluation log */ |
|---|
| 102 | + |
|---|
| 103 | + ACPI_DEBUG_PRINT_RAW((ACPI_DB_EVALUATION, |
|---|
| 104 | + "%-26s: %s (%s)\n", " Enter evaluation", |
|---|
| 105 | + &info->full_pathname[1], |
|---|
| 106 | + acpi_ut_get_type_name(info->node->type))); |
|---|
| 106 | 107 | |
|---|
| 107 | 108 | /* Count the number of arguments being passed in */ |
|---|
| 108 | 109 | |
|---|
| .. | .. |
|---|
| 289 | 290 | info->relative_pathname)); |
|---|
| 290 | 291 | |
|---|
| 291 | 292 | cleanup: |
|---|
| 293 | + /* Optional object evaluation log */ |
|---|
| 294 | + |
|---|
| 295 | + ACPI_DEBUG_PRINT_RAW((ACPI_DB_EVALUATION, |
|---|
| 296 | + "%-26s: %s\n", " Exit evaluation", |
|---|
| 297 | + &info->full_pathname[1])); |
|---|
| 298 | + |
|---|
| 292 | 299 | /* |
|---|
| 293 | 300 | * Namespace was unlocked by the handling acpi_ns* function, so we |
|---|
| 294 | 301 | * just free the pathname and return |
|---|
| .. | .. |
|---|
| 296 | 303 | ACPI_FREE(info->full_pathname); |
|---|
| 297 | 304 | info->full_pathname = NULL; |
|---|
| 298 | 305 | return_ACPI_STATUS(status); |
|---|
| 299 | | -} |
|---|
| 300 | | - |
|---|
| 301 | | -/******************************************************************************* |
|---|
| 302 | | - * |
|---|
| 303 | | - * FUNCTION: acpi_ns_exec_module_code_list |
|---|
| 304 | | - * |
|---|
| 305 | | - * PARAMETERS: None |
|---|
| 306 | | - * |
|---|
| 307 | | - * RETURN: None. Exceptions during method execution are ignored, since |
|---|
| 308 | | - * we cannot abort a table load. |
|---|
| 309 | | - * |
|---|
| 310 | | - * DESCRIPTION: Execute all elements of the global module-level code list. |
|---|
| 311 | | - * Each element is executed as a single control method. |
|---|
| 312 | | - * |
|---|
| 313 | | - * NOTE: With this option enabled, each block of detected executable AML |
|---|
| 314 | | - * code that is outside of any control method is wrapped with a temporary |
|---|
| 315 | | - * control method object and placed on a global list. The methods on this |
|---|
| 316 | | - * list are executed below. |
|---|
| 317 | | - * |
|---|
| 318 | | - * This function executes the module-level code for all tables only after |
|---|
| 319 | | - * all of the tables have been loaded. It is a legacy option and is |
|---|
| 320 | | - * not compatible with other ACPI implementations. See acpi_ns_load_table. |
|---|
| 321 | | - * |
|---|
| 322 | | - * This function will be removed when the legacy option is removed. |
|---|
| 323 | | - * |
|---|
| 324 | | - ******************************************************************************/ |
|---|
| 325 | | - |
|---|
| 326 | | -void acpi_ns_exec_module_code_list(void) |
|---|
| 327 | | -{ |
|---|
| 328 | | - union acpi_operand_object *prev; |
|---|
| 329 | | - union acpi_operand_object *next; |
|---|
| 330 | | - struct acpi_evaluate_info *info; |
|---|
| 331 | | - u32 method_count = 0; |
|---|
| 332 | | - |
|---|
| 333 | | - ACPI_FUNCTION_TRACE(ns_exec_module_code_list); |
|---|
| 334 | | - |
|---|
| 335 | | - /* Exit now if the list is empty */ |
|---|
| 336 | | - |
|---|
| 337 | | - next = acpi_gbl_module_code_list; |
|---|
| 338 | | - if (!next) { |
|---|
| 339 | | - ACPI_DEBUG_PRINT((ACPI_DB_INIT_NAMES, |
|---|
| 340 | | - "Legacy MLC block list is empty\n")); |
|---|
| 341 | | - |
|---|
| 342 | | - return_VOID; |
|---|
| 343 | | - } |
|---|
| 344 | | - |
|---|
| 345 | | - /* Allocate the evaluation information block */ |
|---|
| 346 | | - |
|---|
| 347 | | - info = ACPI_ALLOCATE(sizeof(struct acpi_evaluate_info)); |
|---|
| 348 | | - if (!info) { |
|---|
| 349 | | - return_VOID; |
|---|
| 350 | | - } |
|---|
| 351 | | - |
|---|
| 352 | | - /* Walk the list, executing each "method" */ |
|---|
| 353 | | - |
|---|
| 354 | | - while (next) { |
|---|
| 355 | | - prev = next; |
|---|
| 356 | | - next = next->method.mutex; |
|---|
| 357 | | - |
|---|
| 358 | | - /* Clear the link field and execute the method */ |
|---|
| 359 | | - |
|---|
| 360 | | - prev->method.mutex = NULL; |
|---|
| 361 | | - acpi_ns_exec_module_code(prev, info); |
|---|
| 362 | | - method_count++; |
|---|
| 363 | | - |
|---|
| 364 | | - /* Delete the (temporary) method object */ |
|---|
| 365 | | - |
|---|
| 366 | | - acpi_ut_remove_reference(prev); |
|---|
| 367 | | - } |
|---|
| 368 | | - |
|---|
| 369 | | - ACPI_INFO(("Executed %u blocks of module-level executable AML code", |
|---|
| 370 | | - method_count)); |
|---|
| 371 | | - |
|---|
| 372 | | - ACPI_FREE(info); |
|---|
| 373 | | - acpi_gbl_module_code_list = NULL; |
|---|
| 374 | | - return_VOID; |
|---|
| 375 | | -} |
|---|
| 376 | | - |
|---|
| 377 | | -/******************************************************************************* |
|---|
| 378 | | - * |
|---|
| 379 | | - * FUNCTION: acpi_ns_exec_module_code |
|---|
| 380 | | - * |
|---|
| 381 | | - * PARAMETERS: method_obj - Object container for the module-level code |
|---|
| 382 | | - * info - Info block for method evaluation |
|---|
| 383 | | - * |
|---|
| 384 | | - * RETURN: None. Exceptions during method execution are ignored, since |
|---|
| 385 | | - * we cannot abort a table load. |
|---|
| 386 | | - * |
|---|
| 387 | | - * DESCRIPTION: Execute a control method containing a block of module-level |
|---|
| 388 | | - * executable AML code. The control method is temporarily |
|---|
| 389 | | - * installed to the root node, then evaluated. |
|---|
| 390 | | - * |
|---|
| 391 | | - ******************************************************************************/ |
|---|
| 392 | | - |
|---|
| 393 | | -static void |
|---|
| 394 | | -acpi_ns_exec_module_code(union acpi_operand_object *method_obj, |
|---|
| 395 | | - struct acpi_evaluate_info *info) |
|---|
| 396 | | -{ |
|---|
| 397 | | - union acpi_operand_object *parent_obj; |
|---|
| 398 | | - struct acpi_namespace_node *parent_node; |
|---|
| 399 | | - acpi_object_type type; |
|---|
| 400 | | - acpi_status status; |
|---|
| 401 | | - |
|---|
| 402 | | - ACPI_FUNCTION_TRACE(ns_exec_module_code); |
|---|
| 403 | | - |
|---|
| 404 | | - /* |
|---|
| 405 | | - * Get the parent node. We cheat by using the next_object field |
|---|
| 406 | | - * of the method object descriptor. |
|---|
| 407 | | - */ |
|---|
| 408 | | - parent_node = |
|---|
| 409 | | - ACPI_CAST_PTR(struct acpi_namespace_node, |
|---|
| 410 | | - method_obj->method.next_object); |
|---|
| 411 | | - type = acpi_ns_get_type(parent_node); |
|---|
| 412 | | - |
|---|
| 413 | | - /* |
|---|
| 414 | | - * Get the region handler and save it in the method object. We may need |
|---|
| 415 | | - * this if an operation region declaration causes a _REG method to be run. |
|---|
| 416 | | - * |
|---|
| 417 | | - * We can't do this in acpi_ps_link_module_code because |
|---|
| 418 | | - * acpi_gbl_root_node->Object is NULL at PASS1. |
|---|
| 419 | | - */ |
|---|
| 420 | | - if ((type == ACPI_TYPE_DEVICE) && parent_node->object) { |
|---|
| 421 | | - method_obj->method.dispatch.handler = |
|---|
| 422 | | - parent_node->object->device.handler; |
|---|
| 423 | | - } |
|---|
| 424 | | - |
|---|
| 425 | | - /* Must clear next_object (acpi_ns_attach_object needs the field) */ |
|---|
| 426 | | - |
|---|
| 427 | | - method_obj->method.next_object = NULL; |
|---|
| 428 | | - |
|---|
| 429 | | - /* Initialize the evaluation information block */ |
|---|
| 430 | | - |
|---|
| 431 | | - memset(info, 0, sizeof(struct acpi_evaluate_info)); |
|---|
| 432 | | - info->prefix_node = parent_node; |
|---|
| 433 | | - |
|---|
| 434 | | - /* |
|---|
| 435 | | - * Get the currently attached parent object. Add a reference, |
|---|
| 436 | | - * because the ref count will be decreased when the method object |
|---|
| 437 | | - * is installed to the parent node. |
|---|
| 438 | | - */ |
|---|
| 439 | | - parent_obj = acpi_ns_get_attached_object(parent_node); |
|---|
| 440 | | - if (parent_obj) { |
|---|
| 441 | | - acpi_ut_add_reference(parent_obj); |
|---|
| 442 | | - } |
|---|
| 443 | | - |
|---|
| 444 | | - /* Install the method (module-level code) in the parent node */ |
|---|
| 445 | | - |
|---|
| 446 | | - status = |
|---|
| 447 | | - acpi_ns_attach_object(parent_node, method_obj, ACPI_TYPE_METHOD); |
|---|
| 448 | | - if (ACPI_FAILURE(status)) { |
|---|
| 449 | | - goto exit; |
|---|
| 450 | | - } |
|---|
| 451 | | - |
|---|
| 452 | | - /* Execute the parent node as a control method */ |
|---|
| 453 | | - |
|---|
| 454 | | - status = acpi_ns_evaluate(info); |
|---|
| 455 | | - |
|---|
| 456 | | - ACPI_DEBUG_PRINT((ACPI_DB_INIT_NAMES, |
|---|
| 457 | | - "Executed module-level code at %p\n", |
|---|
| 458 | | - method_obj->method.aml_start)); |
|---|
| 459 | | - |
|---|
| 460 | | - /* Delete a possible implicit return value (in slack mode) */ |
|---|
| 461 | | - |
|---|
| 462 | | - if (info->return_object) { |
|---|
| 463 | | - acpi_ut_remove_reference(info->return_object); |
|---|
| 464 | | - } |
|---|
| 465 | | - |
|---|
| 466 | | - /* Detach the temporary method object */ |
|---|
| 467 | | - |
|---|
| 468 | | - acpi_ns_detach_object(parent_node); |
|---|
| 469 | | - |
|---|
| 470 | | - /* Restore the original parent object */ |
|---|
| 471 | | - |
|---|
| 472 | | - if (parent_obj) { |
|---|
| 473 | | - status = acpi_ns_attach_object(parent_node, parent_obj, type); |
|---|
| 474 | | - } else { |
|---|
| 475 | | - parent_node->type = (u8)type; |
|---|
| 476 | | - } |
|---|
| 477 | | - |
|---|
| 478 | | -exit: |
|---|
| 479 | | - if (parent_obj) { |
|---|
| 480 | | - acpi_ut_remove_reference(parent_obj); |
|---|
| 481 | | - } |
|---|
| 482 | | - return_VOID; |
|---|
| 483 | 306 | } |
|---|