1205 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/*******************************************************************************3 *4 * Module Name: dbcmds - Miscellaneous debug commands and output routines5 *6 ******************************************************************************/7 8#include <acpi/acpi.h>9#include "accommon.h"10#include "acevents.h"11#include "acdebug.h"12#include "acnamesp.h"13#include "acresrc.h"14#include "actables.h"15 16#define _COMPONENT ACPI_CA_DEBUGGER17ACPI_MODULE_NAME("dbcmds")18 19/* Local prototypes */20static void21acpi_dm_compare_aml_resources(u8 *aml1_buffer,22 acpi_rsdesc_size aml1_buffer_length,23 u8 *aml2_buffer,24 acpi_rsdesc_size aml2_buffer_length);25 26static acpi_status27acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name);28 29static acpi_status30acpi_db_resource_callback(struct acpi_resource *resource, void *context);31 32static acpi_status33acpi_db_device_resources(acpi_handle obj_handle,34 u32 nesting_level, void *context, void **return_value);35 36static void acpi_db_do_one_sleep_state(u8 sleep_state);37 38static char *acpi_db_trace_method_name = NULL;39 40/*******************************************************************************41 *42 * FUNCTION: acpi_db_convert_to_node43 *44 * PARAMETERS: in_string - String to convert45 *46 * RETURN: Pointer to a NS node47 *48 * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or49 * alphanumeric strings.50 *51 ******************************************************************************/52 53struct acpi_namespace_node *acpi_db_convert_to_node(char *in_string)54{55 struct acpi_namespace_node *node;56 acpi_size address;57 58 if ((*in_string >= 0x30) && (*in_string <= 0x39)) {59 60 /* Numeric argument, convert */61 62 address = strtoul(in_string, NULL, 16);63 node = ACPI_TO_POINTER(address);64 if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) {65 acpi_os_printf("Address %p is invalid", node);66 return (NULL);67 }68 69 /* Make sure pointer is valid NS node */70 71 if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {72 acpi_os_printf73 ("Address %p is not a valid namespace node [%s]\n",74 node, acpi_ut_get_descriptor_name(node));75 return (NULL);76 }77 } else {78 /*79 * Alpha argument: The parameter is a name string that must be80 * resolved to a Namespace object.81 */82 node = acpi_db_local_ns_lookup(in_string);83 if (!node) {84 acpi_os_printf85 ("Could not find [%s] in namespace, defaulting to root node\n",86 in_string);87 node = acpi_gbl_root_node;88 }89 }90 91 return (node);92}93 94/*******************************************************************************95 *96 * FUNCTION: acpi_db_sleep97 *98 * PARAMETERS: object_arg - Desired sleep state (0-5). NULL means99 * invoke all possible sleep states.100 *101 * RETURN: Status102 *103 * DESCRIPTION: Simulate sleep/wake sequences104 *105 ******************************************************************************/106 107acpi_status acpi_db_sleep(char *object_arg)108{109 u8 sleep_state;110 u32 i;111 112 ACPI_FUNCTION_TRACE(acpi_db_sleep);113 114 /* Null input (no arguments) means to invoke all sleep states */115 116 if (!object_arg) {117 acpi_os_printf("Invoking all possible sleep states, 0-%d\n",118 ACPI_S_STATES_MAX);119 120 for (i = 0; i <= ACPI_S_STATES_MAX; i++) {121 acpi_db_do_one_sleep_state((u8)i);122 }123 124 return_ACPI_STATUS(AE_OK);125 }126 127 /* Convert argument to binary and invoke the sleep state */128 129 sleep_state = (u8)strtoul(object_arg, NULL, 0);130 acpi_db_do_one_sleep_state(sleep_state);131 return_ACPI_STATUS(AE_OK);132}133 134/*******************************************************************************135 *136 * FUNCTION: acpi_db_do_one_sleep_state137 *138 * PARAMETERS: sleep_state - Desired sleep state (0-5)139 *140 * RETURN: None141 *142 * DESCRIPTION: Simulate a sleep/wake sequence143 *144 ******************************************************************************/145 146static void acpi_db_do_one_sleep_state(u8 sleep_state)147{148 acpi_status status;149 u8 sleep_type_a;150 u8 sleep_type_b;151 152 /* Validate parameter */153 154 if (sleep_state > ACPI_S_STATES_MAX) {155 acpi_os_printf("Sleep state %d out of range (%d max)\n",156 sleep_state, ACPI_S_STATES_MAX);157 return;158 }159 160 acpi_os_printf("\n---- Invoking sleep state S%d (%s):\n",161 sleep_state, acpi_gbl_sleep_state_names[sleep_state]);162 163 /* Get the values for the sleep type registers (for display only) */164 165 status =166 acpi_get_sleep_type_data(sleep_state, &sleep_type_a, &sleep_type_b);167 if (ACPI_FAILURE(status)) {168 acpi_os_printf("Could not evaluate [%s] method, %s\n",169 acpi_gbl_sleep_state_names[sleep_state],170 acpi_format_exception(status));171 return;172 }173 174 acpi_os_printf175 ("Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n",176 sleep_state, sleep_type_a, sleep_type_b);177 178 /* Invoke the various sleep/wake interfaces */179 180 acpi_os_printf("**** Sleep: Prepare to sleep (S%d) ****\n",181 sleep_state);182 status = acpi_enter_sleep_state_prep(sleep_state);183 if (ACPI_FAILURE(status)) {184 goto error_exit;185 }186 187 acpi_os_printf("**** Sleep: Going to sleep (S%d) ****\n", sleep_state);188 status = acpi_enter_sleep_state(sleep_state);189 if (ACPI_FAILURE(status)) {190 goto error_exit;191 }192 193 acpi_os_printf("**** Wake: Prepare to return from sleep (S%d) ****\n",194 sleep_state);195 status = acpi_leave_sleep_state_prep(sleep_state);196 if (ACPI_FAILURE(status)) {197 goto error_exit;198 }199 200 acpi_os_printf("**** Wake: Return from sleep (S%d) ****\n",201 sleep_state);202 status = acpi_leave_sleep_state(sleep_state);203 if (ACPI_FAILURE(status)) {204 goto error_exit;205 }206 207 return;208 209error_exit:210 ACPI_EXCEPTION((AE_INFO, status, "During invocation of sleep state S%d",211 sleep_state));212}213 214/*******************************************************************************215 *216 * FUNCTION: acpi_db_display_locks217 *218 * PARAMETERS: None219 *220 * RETURN: None221 *222 * DESCRIPTION: Display information about internal mutexes.223 *224 ******************************************************************************/225 226void acpi_db_display_locks(void)227{228 u32 i;229 230 for (i = 0; i < ACPI_MAX_MUTEX; i++) {231 acpi_os_printf("%26s : %s\n", acpi_ut_get_mutex_name(i),232 acpi_gbl_mutex_info[i].thread_id ==233 ACPI_MUTEX_NOT_ACQUIRED ? "Locked" : "Unlocked");234 }235}236 237/*******************************************************************************238 *239 * FUNCTION: acpi_db_display_table_info240 *241 * PARAMETERS: table_arg - Name of table to be displayed242 *243 * RETURN: None244 *245 * DESCRIPTION: Display information about loaded tables. Current246 * implementation displays all loaded tables.247 *248 ******************************************************************************/249 250void acpi_db_display_table_info(char *table_arg)251{252 u32 i;253 struct acpi_table_desc *table_desc;254 acpi_status status;255 256 /* Header */257 258 acpi_os_printf("Idx ID Status Type "259 "TableHeader (Sig, Address, Length, Misc)\n");260 261 /* Walk the entire root table list */262 263 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {264 table_desc = &acpi_gbl_root_table_list.tables[i];265 266 /* Index and Table ID */267 268 acpi_os_printf("%3u %.2u ", i, table_desc->owner_id);269 270 /* Decode the table flags */271 272 if (!(table_desc->flags & ACPI_TABLE_IS_LOADED)) {273 acpi_os_printf("NotLoaded ");274 } else {275 acpi_os_printf(" Loaded ");276 }277 278 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {279 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:280 281 acpi_os_printf("External/virtual ");282 break;283 284 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:285 286 acpi_os_printf("Internal/physical ");287 break;288 289 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:290 291 acpi_os_printf("Internal/virtual ");292 break;293 294 default:295 296 acpi_os_printf("INVALID TYPE ");297 break;298 }299 300 /* Make sure that the table is mapped */301 302 status = acpi_tb_validate_table(table_desc);303 if (ACPI_FAILURE(status)) {304 return;305 }306 307 /* Dump the table header */308 309 if (table_desc->pointer) {310 acpi_tb_print_table_header(table_desc->address,311 table_desc->pointer);312 } else {313 /* If the pointer is null, the table has been unloaded */314 315 ACPI_INFO(("%4.4s - Table has been unloaded",316 table_desc->signature.ascii));317 }318 }319}320 321/*******************************************************************************322 *323 * FUNCTION: acpi_db_unload_acpi_table324 *325 * PARAMETERS: object_name - Namespace pathname for an object that326 * is owned by the table to be unloaded327 *328 * RETURN: None329 *330 * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned331 * by the table.332 *333 ******************************************************************************/334 335void acpi_db_unload_acpi_table(char *object_name)336{337 struct acpi_namespace_node *node;338 acpi_status status;339 340 /* Translate name to an Named object */341 342 node = acpi_db_convert_to_node(object_name);343 if (!node) {344 return;345 }346 347 status = acpi_unload_parent_table(ACPI_CAST_PTR(acpi_handle, node));348 if (ACPI_SUCCESS(status)) {349 acpi_os_printf("Parent of [%s] (%p) unloaded and uninstalled\n",350 object_name, node);351 } else {352 acpi_os_printf("%s, while unloading parent table of [%s]\n",353 acpi_format_exception(status), object_name);354 }355}356 357/*******************************************************************************358 *359 * FUNCTION: acpi_db_send_notify360 *361 * PARAMETERS: name - Name of ACPI object where to send notify362 * value - Value of the notify to send.363 *364 * RETURN: None365 *366 * DESCRIPTION: Send an ACPI notification. The value specified is sent to the367 * named object as an ACPI notify.368 *369 ******************************************************************************/370 371void acpi_db_send_notify(char *name, u32 value)372{373 struct acpi_namespace_node *node;374 acpi_status status;375 376 /* Translate name to an Named object */377 378 node = acpi_db_convert_to_node(name);379 if (!node) {380 return;381 }382 383 /* Dispatch the notify if legal */384 385 if (acpi_ev_is_notify_object(node)) {386 status = acpi_ev_queue_notify_request(node, value);387 if (ACPI_FAILURE(status)) {388 acpi_os_printf("Could not queue notify\n");389 }390 } else {391 acpi_os_printf("Named object [%4.4s] Type %s, "392 "must be Device/Thermal/Processor type\n",393 acpi_ut_get_node_name(node),394 acpi_ut_get_type_name(node->type));395 }396}397 398/*******************************************************************************399 *400 * FUNCTION: acpi_db_display_interfaces401 *402 * PARAMETERS: action_arg - Null, "install", or "remove"403 * interface_name_arg - Name for install/remove options404 *405 * RETURN: None406 *407 * DESCRIPTION: Display or modify the global _OSI interface list408 *409 ******************************************************************************/410 411void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg)412{413 struct acpi_interface_info *next_interface;414 char *sub_string;415 acpi_status status;416 417 /* If no arguments, just display current interface list */418 419 if (!action_arg) {420 (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex,421 ACPI_WAIT_FOREVER);422 423 next_interface = acpi_gbl_supported_interfaces;424 while (next_interface) {425 if (!(next_interface->flags & ACPI_OSI_INVALID)) {426 acpi_os_printf("%s\n", next_interface->name);427 }428 429 next_interface = next_interface->next;430 }431 432 acpi_os_release_mutex(acpi_gbl_osi_mutex);433 return;434 }435 436 /* If action_arg exists, so must interface_name_arg */437 438 if (!interface_name_arg) {439 acpi_os_printf("Missing Interface Name argument\n");440 return;441 }442 443 /* Uppercase the action for match below */444 445 acpi_ut_strupr(action_arg);446 447 /* install - install an interface */448 449 sub_string = strstr("INSTALL", action_arg);450 if (sub_string) {451 status = acpi_install_interface(interface_name_arg);452 if (ACPI_FAILURE(status)) {453 acpi_os_printf("%s, while installing \"%s\"\n",454 acpi_format_exception(status),455 interface_name_arg);456 }457 return;458 }459 460 /* remove - remove an interface */461 462 sub_string = strstr("REMOVE", action_arg);463 if (sub_string) {464 status = acpi_remove_interface(interface_name_arg);465 if (ACPI_FAILURE(status)) {466 acpi_os_printf("%s, while removing \"%s\"\n",467 acpi_format_exception(status),468 interface_name_arg);469 }470 return;471 }472 473 /* Invalid action_arg */474 475 acpi_os_printf("Invalid action argument: %s\n", action_arg);476 return;477}478 479/*******************************************************************************480 *481 * FUNCTION: acpi_db_display_template482 *483 * PARAMETERS: buffer_arg - Buffer name or address484 *485 * RETURN: None486 *487 * DESCRIPTION: Dump a buffer that contains a resource template488 *489 ******************************************************************************/490 491void acpi_db_display_template(char *buffer_arg)492{493 struct acpi_namespace_node *node;494 acpi_status status;495 struct acpi_buffer return_buffer;496 497 /* Translate buffer_arg to an Named object */498 499 node = acpi_db_convert_to_node(buffer_arg);500 if (!node || (node == acpi_gbl_root_node)) {501 acpi_os_printf("Invalid argument: %s\n", buffer_arg);502 return;503 }504 505 /* We must have a buffer object */506 507 if (node->type != ACPI_TYPE_BUFFER) {508 acpi_os_printf509 ("Not a Buffer object, cannot be a template: %s\n",510 buffer_arg);511 return;512 }513 514 return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;515 return_buffer.pointer = acpi_gbl_db_buffer;516 517 /* Attempt to convert the raw buffer to a resource list */518 519 status = acpi_rs_create_resource_list(node->object, &return_buffer);520 521 acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);522 acpi_dbg_level |= ACPI_LV_RESOURCES;523 524 if (ACPI_FAILURE(status)) {525 acpi_os_printf526 ("Could not convert Buffer to a resource list: %s, %s\n",527 buffer_arg, acpi_format_exception(status));528 goto dump_buffer;529 }530 531 /* Now we can dump the resource list */532 533 acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,534 return_buffer.pointer));535 536dump_buffer:537 acpi_os_printf("\nRaw data buffer:\n");538 acpi_ut_debug_dump_buffer((u8 *)node->object->buffer.pointer,539 node->object->buffer.length,540 DB_BYTE_DISPLAY, ACPI_UINT32_MAX);541 542 acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);543 return;544}545 546/*******************************************************************************547 *548 * FUNCTION: acpi_dm_compare_aml_resources549 *550 * PARAMETERS: aml1_buffer - Contains first resource list551 * aml1_buffer_length - Length of first resource list552 * aml2_buffer - Contains second resource list553 * aml2_buffer_length - Length of second resource list554 *555 * RETURN: None556 *557 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in558 * order to isolate a miscompare to an individual resource)559 *560 ******************************************************************************/561 562static void563acpi_dm_compare_aml_resources(u8 *aml1_buffer,564 acpi_rsdesc_size aml1_buffer_length,565 u8 *aml2_buffer,566 acpi_rsdesc_size aml2_buffer_length)567{568 u8 *aml1;569 u8 *aml2;570 u8 *aml1_end;571 u8 *aml2_end;572 acpi_rsdesc_size aml1_length;573 acpi_rsdesc_size aml2_length;574 acpi_rsdesc_size offset = 0;575 u8 resource_type;576 u32 count = 0;577 u32 i;578 579 /* Compare overall buffer sizes (may be different due to size rounding) */580 581 if (aml1_buffer_length != aml2_buffer_length) {582 acpi_os_printf("**** Buffer length mismatch in converted "583 "AML: Original %X, New %X ****\n",584 aml1_buffer_length, aml2_buffer_length);585 }586 587 aml1 = aml1_buffer;588 aml2 = aml2_buffer;589 aml1_end = aml1_buffer + aml1_buffer_length;590 aml2_end = aml2_buffer + aml2_buffer_length;591 592 /* Walk the descriptor lists, comparing each descriptor */593 594 while ((aml1 < aml1_end) && (aml2 < aml2_end)) {595 596 /* Get the lengths of each descriptor */597 598 aml1_length = acpi_ut_get_descriptor_length(aml1);599 aml2_length = acpi_ut_get_descriptor_length(aml2);600 resource_type = acpi_ut_get_resource_type(aml1);601 602 /* Check for descriptor length match */603 604 if (aml1_length != aml2_length) {605 acpi_os_printf606 ("**** Length mismatch in descriptor [%.2X] type %2.2X, "607 "Offset %8.8X Len1 %X, Len2 %X ****\n", count,608 resource_type, offset, aml1_length, aml2_length);609 }610 611 /* Check for descriptor byte match */612 613 else if (memcmp(aml1, aml2, aml1_length)) {614 acpi_os_printf615 ("**** Data mismatch in descriptor [%.2X] type %2.2X, "616 "Offset %8.8X ****\n", count, resource_type,617 offset);618 619 for (i = 0; i < aml1_length; i++) {620 if (aml1[i] != aml2[i]) {621 acpi_os_printf622 ("Mismatch at byte offset %.2X: is %2.2X, "623 "should be %2.2X\n", i, aml2[i],624 aml1[i]);625 }626 }627 }628 629 /* Exit on end_tag descriptor */630 631 if (resource_type == ACPI_RESOURCE_NAME_END_TAG) {632 return;633 }634 635 /* Point to next descriptor in each buffer */636 637 count++;638 offset += aml1_length;639 aml1 += aml1_length;640 aml2 += aml2_length;641 }642}643 644/*******************************************************************************645 *646 * FUNCTION: acpi_dm_test_resource_conversion647 *648 * PARAMETERS: node - Parent device node649 * name - resource method name (_CRS)650 *651 * RETURN: Status652 *653 * DESCRIPTION: Compare the original AML with a conversion of the AML to654 * internal resource list, then back to AML.655 *656 ******************************************************************************/657 658static acpi_status659acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name)660{661 acpi_status status;662 struct acpi_buffer return_buffer;663 struct acpi_buffer resource_buffer;664 struct acpi_buffer new_aml;665 union acpi_object *original_aml;666 667 acpi_os_printf("Resource Conversion Comparison:\n");668 669 new_aml.length = ACPI_ALLOCATE_LOCAL_BUFFER;670 return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;671 resource_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;672 673 /* Get the original _CRS AML resource template */674 675 status = acpi_evaluate_object(node, name, NULL, &return_buffer);676 if (ACPI_FAILURE(status)) {677 acpi_os_printf("Could not obtain %s: %s\n",678 name, acpi_format_exception(status));679 return (status);680 }681 682 /* Get the AML resource template, converted to internal resource structs */683 684 status = acpi_get_current_resources(node, &resource_buffer);685 if (ACPI_FAILURE(status)) {686 acpi_os_printf("AcpiGetCurrentResources failed: %s\n",687 acpi_format_exception(status));688 goto exit1;689 }690 691 /* Convert internal resource list to external AML resource template */692 693 status = acpi_rs_create_aml_resources(&resource_buffer, &new_aml);694 if (ACPI_FAILURE(status)) {695 acpi_os_printf("AcpiRsCreateAmlResources failed: %s\n",696 acpi_format_exception(status));697 goto exit2;698 }699 700 /* Compare original AML to the newly created AML resource list */701 702 original_aml = return_buffer.pointer;703 704 acpi_dm_compare_aml_resources(original_aml->buffer.pointer,705 (acpi_rsdesc_size)original_aml->buffer.706 length, new_aml.pointer,707 (acpi_rsdesc_size)new_aml.length);708 709 /* Cleanup and exit */710 711 ACPI_FREE(new_aml.pointer);712exit2:713 ACPI_FREE(resource_buffer.pointer);714exit1:715 ACPI_FREE(return_buffer.pointer);716 return (status);717}718 719/*******************************************************************************720 *721 * FUNCTION: acpi_db_resource_callback722 *723 * PARAMETERS: acpi_walk_resource_callback724 *725 * RETURN: Status726 *727 * DESCRIPTION: Simple callback to exercise acpi_walk_resources and728 * acpi_walk_resource_buffer.729 *730 ******************************************************************************/731 732static acpi_status733acpi_db_resource_callback(struct acpi_resource *resource, void *context)734{735 736 return (AE_OK);737}738 739/*******************************************************************************740 *741 * FUNCTION: acpi_db_device_resources742 *743 * PARAMETERS: acpi_walk_callback744 *745 * RETURN: Status746 *747 * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.748 *749 ******************************************************************************/750 751static acpi_status752acpi_db_device_resources(acpi_handle obj_handle,753 u32 nesting_level, void *context, void **return_value)754{755 struct acpi_namespace_node *node;756 struct acpi_namespace_node *prt_node = NULL;757 struct acpi_namespace_node *crs_node = NULL;758 struct acpi_namespace_node *prs_node = NULL;759 struct acpi_namespace_node *aei_node = NULL;760 char *parent_path;761 struct acpi_buffer return_buffer;762 acpi_status status;763 764 node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);765 parent_path = acpi_ns_get_normalized_pathname(node, TRUE);766 if (!parent_path) {767 return (AE_NO_MEMORY);768 }769 770 /* Get handles to the resource methods for this device */771 772 (void)acpi_get_handle(node, METHOD_NAME__PRT,773 ACPI_CAST_PTR(acpi_handle, &prt_node));774 (void)acpi_get_handle(node, METHOD_NAME__CRS,775 ACPI_CAST_PTR(acpi_handle, &crs_node));776 (void)acpi_get_handle(node, METHOD_NAME__PRS,777 ACPI_CAST_PTR(acpi_handle, &prs_node));778 (void)acpi_get_handle(node, METHOD_NAME__AEI,779 ACPI_CAST_PTR(acpi_handle, &aei_node));780 781 if (!prt_node && !crs_node && !prs_node && !aei_node) {782 goto cleanup; /* Nothing to do */783 }784 785 acpi_os_printf("\nDevice: %s\n", parent_path);786 787 /* Prepare for a return object of arbitrary size */788 789 return_buffer.pointer = acpi_gbl_db_buffer;790 return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;791 792 /* _PRT */793 794 if (prt_node) {795 acpi_os_printf("Evaluating _PRT\n");796 797 status =798 acpi_evaluate_object(prt_node, NULL, NULL, &return_buffer);799 if (ACPI_FAILURE(status)) {800 acpi_os_printf("Could not evaluate _PRT: %s\n",801 acpi_format_exception(status));802 goto get_crs;803 }804 805 return_buffer.pointer = acpi_gbl_db_buffer;806 return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;807 808 status = acpi_get_irq_routing_table(node, &return_buffer);809 if (ACPI_FAILURE(status)) {810 acpi_os_printf("GetIrqRoutingTable failed: %s\n",811 acpi_format_exception(status));812 goto get_crs;813 }814 815 acpi_rs_dump_irq_list(ACPI_CAST_PTR(u8, acpi_gbl_db_buffer));816 }817 818 /* _CRS */819 820get_crs:821 if (crs_node) {822 acpi_os_printf("Evaluating _CRS\n");823 824 return_buffer.pointer = acpi_gbl_db_buffer;825 return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;826 827 status =828 acpi_evaluate_object(crs_node, NULL, NULL, &return_buffer);829 if (ACPI_FAILURE(status)) {830 acpi_os_printf("Could not evaluate _CRS: %s\n",831 acpi_format_exception(status));832 goto get_prs;833 }834 835 /* This code exercises the acpi_walk_resources interface */836 837 status = acpi_walk_resources(node, METHOD_NAME__CRS,838 acpi_db_resource_callback, NULL);839 if (ACPI_FAILURE(status)) {840 acpi_os_printf("AcpiWalkResources failed: %s\n",841 acpi_format_exception(status));842 goto get_prs;843 }844 845 /* Get the _CRS resource list (test ALLOCATE buffer) */846 847 return_buffer.pointer = NULL;848 return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;849 850 status = acpi_get_current_resources(node, &return_buffer);851 if (ACPI_FAILURE(status)) {852 acpi_os_printf("AcpiGetCurrentResources failed: %s\n",853 acpi_format_exception(status));854 goto get_prs;855 }856 857 /* This code exercises the acpi_walk_resource_buffer interface */858 859 status = acpi_walk_resource_buffer(&return_buffer,860 acpi_db_resource_callback,861 NULL);862 if (ACPI_FAILURE(status)) {863 acpi_os_printf("AcpiWalkResourceBuffer failed: %s\n",864 acpi_format_exception(status));865 goto end_crs;866 }867 868 /* Dump the _CRS resource list */869 870 acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,871 return_buffer.872 pointer));873 874 /*875 * Perform comparison of original AML to newly created AML. This876 * tests both the AML->Resource conversion and the Resource->AML877 * conversion.878 */879 (void)acpi_dm_test_resource_conversion(node, METHOD_NAME__CRS);880 881 /* Execute _SRS with the resource list */882 883 acpi_os_printf("Evaluating _SRS\n");884 885 status = acpi_set_current_resources(node, &return_buffer);886 if (ACPI_FAILURE(status)) {887 acpi_os_printf("AcpiSetCurrentResources failed: %s\n",888 acpi_format_exception(status));889 goto end_crs;890 }891 892end_crs:893 ACPI_FREE(return_buffer.pointer);894 }895 896 /* _PRS */897 898get_prs:899 if (prs_node) {900 acpi_os_printf("Evaluating _PRS\n");901 902 return_buffer.pointer = acpi_gbl_db_buffer;903 return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;904 905 status =906 acpi_evaluate_object(prs_node, NULL, NULL, &return_buffer);907 if (ACPI_FAILURE(status)) {908 acpi_os_printf("Could not evaluate _PRS: %s\n",909 acpi_format_exception(status));910 goto get_aei;911 }912 913 return_buffer.pointer = acpi_gbl_db_buffer;914 return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;915 916 status = acpi_get_possible_resources(node, &return_buffer);917 if (ACPI_FAILURE(status)) {918 acpi_os_printf("AcpiGetPossibleResources failed: %s\n",919 acpi_format_exception(status));920 goto get_aei;921 }922 923 acpi_rs_dump_resource_list(ACPI_CAST_PTR924 (struct acpi_resource,925 acpi_gbl_db_buffer));926 }927 928 /* _AEI */929 930get_aei:931 if (aei_node) {932 acpi_os_printf("Evaluating _AEI\n");933 934 return_buffer.pointer = acpi_gbl_db_buffer;935 return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;936 937 status =938 acpi_evaluate_object(aei_node, NULL, NULL, &return_buffer);939 if (ACPI_FAILURE(status)) {940 acpi_os_printf("Could not evaluate _AEI: %s\n",941 acpi_format_exception(status));942 goto cleanup;943 }944 945 return_buffer.pointer = acpi_gbl_db_buffer;946 return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;947 948 status = acpi_get_event_resources(node, &return_buffer);949 if (ACPI_FAILURE(status)) {950 acpi_os_printf("AcpiGetEventResources failed: %s\n",951 acpi_format_exception(status));952 goto cleanup;953 }954 955 acpi_rs_dump_resource_list(ACPI_CAST_PTR956 (struct acpi_resource,957 acpi_gbl_db_buffer));958 }959 960cleanup:961 ACPI_FREE(parent_path);962 return (AE_OK);963}964 965/*******************************************************************************966 *967 * FUNCTION: acpi_db_display_resources968 *969 * PARAMETERS: object_arg - String object name or object pointer.970 * NULL or "*" means "display resources for971 * all devices"972 *973 * RETURN: None974 *975 * DESCRIPTION: Display the resource objects associated with a device.976 *977 ******************************************************************************/978 979void acpi_db_display_resources(char *object_arg)980{981 struct acpi_namespace_node *node;982 983 acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);984 acpi_dbg_level |= ACPI_LV_RESOURCES;985 986 /* Asterisk means "display resources for all devices" */987 988 if (!object_arg || (!strcmp(object_arg, "*"))) {989 (void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,990 ACPI_UINT32_MAX,991 acpi_db_device_resources, NULL, NULL,992 NULL);993 } else {994 /* Convert string to object pointer */995 996 node = acpi_db_convert_to_node(object_arg);997 if (node) {998 if (node->type != ACPI_TYPE_DEVICE) {999 acpi_os_printf1000 ("%4.4s: Name is not a device object (%s)\n",1001 node->name.ascii,1002 acpi_ut_get_type_name(node->type));1003 } else {1004 (void)acpi_db_device_resources(node, 0, NULL,1005 NULL);1006 }1007 }1008 }1009 1010 acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);1011}1012 1013/*******************************************************************************1014 *1015 * FUNCTION: acpi_db_generate_ged1016 *1017 * PARAMETERS: ged_arg - Raw GED number, ascii string1018 *1019 * RETURN: None1020 *1021 * DESCRIPTION: Simulate firing of a GED1022 *1023 ******************************************************************************/1024 1025void acpi_db_generate_interrupt(char *gsiv_arg)1026{1027 u32 gsiv_number;1028 struct acpi_ged_handler_info *ged_info = acpi_gbl_ged_handler_list;1029 1030 if (!ged_info) {1031 acpi_os_printf("No GED handling present\n");1032 }1033 1034 gsiv_number = strtoul(gsiv_arg, NULL, 0);1035 1036 while (ged_info) {1037 1038 if (ged_info->int_id == gsiv_number) {1039 struct acpi_object_list arg_list;1040 union acpi_object arg0;1041 acpi_handle evt_handle = ged_info->evt_method;1042 acpi_status status;1043 1044 acpi_os_printf("Evaluate GED _EVT (GSIV=%d)\n",1045 gsiv_number);1046 1047 if (!evt_handle) {1048 acpi_os_printf("Undefined _EVT method\n");1049 return;1050 }1051 1052 arg0.integer.type = ACPI_TYPE_INTEGER;1053 arg0.integer.value = gsiv_number;1054 1055 arg_list.count = 1;1056 arg_list.pointer = &arg0;1057 1058 status =1059 acpi_evaluate_object(evt_handle, NULL, &arg_list,1060 NULL);1061 if (ACPI_FAILURE(status)) {1062 acpi_os_printf("Could not evaluate _EVT\n");1063 return;1064 }1065 1066 }1067 ged_info = ged_info->next;1068 }1069}1070 1071#if (!ACPI_REDUCED_HARDWARE)1072/*******************************************************************************1073 *1074 * FUNCTION: acpi_db_generate_gpe1075 *1076 * PARAMETERS: gpe_arg - Raw GPE number, ascii string1077 * block_arg - GPE block number, ascii string1078 * 0 or 1 for FADT GPE blocks1079 *1080 * RETURN: None1081 *1082 * DESCRIPTION: Simulate firing of a GPE1083 *1084 ******************************************************************************/1085 1086void acpi_db_generate_gpe(char *gpe_arg, char *block_arg)1087{1088 u32 block_number = 0;1089 u32 gpe_number;1090 struct acpi_gpe_event_info *gpe_event_info;1091 1092 gpe_number = strtoul(gpe_arg, NULL, 0);1093 1094 /*1095 * If no block arg, or block arg == 0 or 1, use the FADT-defined1096 * GPE blocks.1097 */1098 if (block_arg) {1099 block_number = strtoul(block_arg, NULL, 0);1100 if (block_number == 1) {1101 block_number = 0;1102 }1103 }1104 1105 gpe_event_info =1106 acpi_ev_get_gpe_event_info(ACPI_TO_POINTER(block_number),1107 gpe_number);1108 if (!gpe_event_info) {1109 acpi_os_printf("Invalid GPE\n");1110 return;1111 }1112 1113 (void)acpi_ev_gpe_dispatch(NULL, gpe_event_info, gpe_number);1114}1115 1116/*******************************************************************************1117 *1118 * FUNCTION: acpi_db_generate_sci1119 *1120 * PARAMETERS: None1121 *1122 * RETURN: None1123 *1124 * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch.1125 *1126 ******************************************************************************/1127 1128void acpi_db_generate_sci(void)1129{1130 acpi_ev_sci_dispatch();1131}1132 1133#endif /* !ACPI_REDUCED_HARDWARE */1134 1135/*******************************************************************************1136 *1137 * FUNCTION: acpi_db_trace1138 *1139 * PARAMETERS: enable_arg - ENABLE/AML to enable tracer1140 * DISABLE to disable tracer1141 * method_arg - Method to trace1142 * once_arg - Whether trace once1143 *1144 * RETURN: None1145 *1146 * DESCRIPTION: Control method tracing facility1147 *1148 ******************************************************************************/1149 1150void acpi_db_trace(char *enable_arg, char *method_arg, char *once_arg)1151{1152 u32 debug_level = 0;1153 u32 debug_layer = 0;1154 u32 flags = 0;1155 1156 acpi_ut_strupr(enable_arg);1157 acpi_ut_strupr(once_arg);1158 1159 if (method_arg) {1160 if (acpi_db_trace_method_name) {1161 ACPI_FREE(acpi_db_trace_method_name);1162 acpi_db_trace_method_name = NULL;1163 }1164 1165 acpi_db_trace_method_name =1166 ACPI_ALLOCATE(strlen(method_arg) + 1);1167 if (!acpi_db_trace_method_name) {1168 acpi_os_printf("Failed to allocate method name (%s)\n",1169 method_arg);1170 return;1171 }1172 1173 strcpy(acpi_db_trace_method_name, method_arg);1174 }1175 1176 if (!strcmp(enable_arg, "ENABLE") ||1177 !strcmp(enable_arg, "METHOD") || !strcmp(enable_arg, "OPCODE")) {1178 if (!strcmp(enable_arg, "ENABLE")) {1179 1180 /* Inherit current console settings */1181 1182 debug_level = acpi_gbl_db_console_debug_level;1183 debug_layer = acpi_dbg_layer;1184 } else {1185 /* Restrict console output to trace points only */1186 1187 debug_level = ACPI_LV_TRACE_POINT;1188 debug_layer = ACPI_EXECUTER;1189 }1190 1191 flags = ACPI_TRACE_ENABLED;1192 1193 if (!strcmp(enable_arg, "OPCODE")) {1194 flags |= ACPI_TRACE_OPCODE;1195 }1196 1197 if (once_arg && !strcmp(once_arg, "ONCE")) {1198 flags |= ACPI_TRACE_ONESHOT;1199 }1200 }1201 1202 (void)acpi_debug_trace(acpi_db_trace_method_name,1203 debug_level, debug_layer, flags);1204}1205