root/drivers/acpi/acpica/dbcmds.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. acpi_db_convert_to_node
  2. acpi_db_sleep
  3. acpi_db_do_one_sleep_state
  4. acpi_db_display_locks
  5. acpi_db_display_table_info
  6. acpi_db_unload_acpi_table
  7. acpi_db_send_notify
  8. acpi_db_display_interfaces
  9. acpi_db_display_template
  10. acpi_dm_compare_aml_resources
  11. acpi_dm_test_resource_conversion
  12. acpi_db_resource_callback
  13. acpi_db_device_resources
  14. acpi_db_display_resources
  15. acpi_db_generate_gpe
  16. acpi_db_generate_sci
  17. acpi_db_trace

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /*******************************************************************************
   3  *
   4  * Module Name: dbcmds - Miscellaneous debug commands and output routines
   5  *
   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_DEBUGGER
  17 ACPI_MODULE_NAME("dbcmds")
  18 
  19 /* Local prototypes */
  20 static void
  21 acpi_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 
  26 static acpi_status
  27 acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name);
  28 
  29 static acpi_status
  30 acpi_db_resource_callback(struct acpi_resource *resource, void *context);
  31 
  32 static acpi_status
  33 acpi_db_device_resources(acpi_handle obj_handle,
  34                          u32 nesting_level, void *context, void **return_value);
  35 
  36 static void acpi_db_do_one_sleep_state(u8 sleep_state);
  37 
  38 static char *acpi_db_trace_method_name = NULL;
  39 
  40 /*******************************************************************************
  41  *
  42  * FUNCTION:    acpi_db_convert_to_node
  43  *
  44  * PARAMETERS:  in_string           - String to convert
  45  *
  46  * RETURN:      Pointer to a NS node
  47  *
  48  * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
  49  *              alphanumeric strings.
  50  *
  51  ******************************************************************************/
  52 
  53 struct 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_printf
  73                             ("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 be
  80                  * resolved to a Namespace object.
  81                  */
  82                 node = acpi_db_local_ns_lookup(in_string);
  83                 if (!node) {
  84                         acpi_os_printf
  85                             ("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_sleep
  97  *
  98  * PARAMETERS:  object_arg          - Desired sleep state (0-5). NULL means
  99  *                                    invoke all possible sleep states.
 100  *
 101  * RETURN:      Status
 102  *
 103  * DESCRIPTION: Simulate sleep/wake sequences
 104  *
 105  ******************************************************************************/
 106 
 107 acpi_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_state
 137  *
 138  * PARAMETERS:  sleep_state         - Desired sleep state (0-5)
 139  *
 140  * RETURN:      None
 141  *
 142  * DESCRIPTION: Simulate a sleep/wake sequence
 143  *
 144  ******************************************************************************/
 145 
 146 static 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_printf
 175             ("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 
 209 error_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_locks
 217  *
 218  * PARAMETERS:  None
 219  *
 220  * RETURN:      None
 221  *
 222  * DESCRIPTION: Display information about internal mutexes.
 223  *
 224  ******************************************************************************/
 225 
 226 void 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_info
 240  *
 241  * PARAMETERS:  table_arg           - Name of table to be displayed
 242  *
 243  * RETURN:      None
 244  *
 245  * DESCRIPTION: Display information about loaded tables. Current
 246  *              implementation displays all loaded tables.
 247  *
 248  ******************************************************************************/
 249 
 250 void 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_table
 324  *
 325  * PARAMETERS:  object_name         - Namespace pathname for an object that
 326  *                                    is owned by the table to be unloaded
 327  *
 328  * RETURN:      None
 329  *
 330  * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
 331  *              by the table.
 332  *
 333  ******************************************************************************/
 334 
 335 void 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_notify
 360  *
 361  * PARAMETERS:  name                - Name of ACPI object where to send notify
 362  *              value               - Value of the notify to send.
 363  *
 364  * RETURN:      None
 365  *
 366  * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
 367  *              named object as an ACPI notify.
 368  *
 369  ******************************************************************************/
 370 
 371 void 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_interfaces
 401  *
 402  * PARAMETERS:  action_arg          - Null, "install", or "remove"
 403  *              interface_name_arg  - Name for install/remove options
 404  *
 405  * RETURN:      None
 406  *
 407  * DESCRIPTION: Display or modify the global _OSI interface list
 408  *
 409  ******************************************************************************/
 410 
 411 void 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_template
 482  *
 483  * PARAMETERS:  buffer_arg          - Buffer name or address
 484  *
 485  * RETURN:      None
 486  *
 487  * DESCRIPTION: Dump a buffer that contains a resource template
 488  *
 489  ******************************************************************************/
 490 
 491 void 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_printf
 509                     ("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_printf
 526                     ("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 
 536 dump_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_resources
 549  *
 550  * PARAMETERS:  aml1_buffer         - Contains first resource list
 551  *              aml1_buffer_length  - Length of first resource list
 552  *              aml2_buffer         - Contains second resource list
 553  *              aml2_buffer_length  - Length of second resource list
 554  *
 555  * RETURN:      None
 556  *
 557  * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
 558  *              order to isolate a miscompare to an individual resource)
 559  *
 560  ******************************************************************************/
 561 
 562 static void
 563 acpi_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_printf
 606                             ("**** 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_printf
 615                             ("**** 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_printf
 622                                             ("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_conversion
 647  *
 648  * PARAMETERS:  node                - Parent device node
 649  *              name                - resource method name (_CRS)
 650  *
 651  * RETURN:      Status
 652  *
 653  * DESCRIPTION: Compare the original AML with a conversion of the AML to
 654  *              internal resource list, then back to AML.
 655  *
 656  ******************************************************************************/
 657 
 658 static acpi_status
 659 acpi_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);
 712 exit2:
 713         ACPI_FREE(resource_buffer.pointer);
 714 exit1:
 715         ACPI_FREE(return_buffer.pointer);
 716         return (status);
 717 }
 718 
 719 /*******************************************************************************
 720  *
 721  * FUNCTION:    acpi_db_resource_callback
 722  *
 723  * PARAMETERS:  acpi_walk_resource_callback
 724  *
 725  * RETURN:      Status
 726  *
 727  * DESCRIPTION: Simple callback to exercise acpi_walk_resources and
 728  *              acpi_walk_resource_buffer.
 729  *
 730  ******************************************************************************/
 731 
 732 static acpi_status
 733 acpi_db_resource_callback(struct acpi_resource *resource, void *context)
 734 {
 735 
 736         return (AE_OK);
 737 }
 738 
 739 /*******************************************************************************
 740  *
 741  * FUNCTION:    acpi_db_device_resources
 742  *
 743  * PARAMETERS:  acpi_walk_callback
 744  *
 745  * RETURN:      Status
 746  *
 747  * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
 748  *
 749  ******************************************************************************/
 750 
 751 static acpi_status
 752 acpi_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 
 820 get_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. This
 876                  * tests both the AML->Resource conversion and the Resource->AML
 877                  * 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 
 892 end_crs:
 893                 ACPI_FREE(return_buffer.pointer);
 894         }
 895 
 896         /* _PRS */
 897 
 898 get_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_PTR
 924                                            (struct acpi_resource,
 925                                             acpi_gbl_db_buffer));
 926         }
 927 
 928         /* _AEI */
 929 
 930 get_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_PTR
 956                                            (struct acpi_resource,
 957                                             acpi_gbl_db_buffer));
 958         }
 959 
 960 cleanup:
 961         ACPI_FREE(parent_path);
 962         return (AE_OK);
 963 }
 964 
 965 /*******************************************************************************
 966  *
 967  * FUNCTION:    acpi_db_display_resources
 968  *
 969  * PARAMETERS:  object_arg          - String object name or object pointer.
 970  *                                    NULL or "*" means "display resources for
 971  *                                    all devices"
 972  *
 973  * RETURN:      None
 974  *
 975  * DESCRIPTION: Display the resource objects associated with a device.
 976  *
 977  ******************************************************************************/
 978 
 979 void 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_printf
1000                                     ("%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 #if (!ACPI_REDUCED_HARDWARE)
1014 /*******************************************************************************
1015  *
1016  * FUNCTION:    acpi_db_generate_gpe
1017  *
1018  * PARAMETERS:  gpe_arg             - Raw GPE number, ascii string
1019  *              block_arg           - GPE block number, ascii string
1020  *                                    0 or 1 for FADT GPE blocks
1021  *
1022  * RETURN:      None
1023  *
1024  * DESCRIPTION: Simulate firing of a GPE
1025  *
1026  ******************************************************************************/
1027 
1028 void acpi_db_generate_gpe(char *gpe_arg, char *block_arg)
1029 {
1030         u32 block_number = 0;
1031         u32 gpe_number;
1032         struct acpi_gpe_event_info *gpe_event_info;
1033 
1034         gpe_number = strtoul(gpe_arg, NULL, 0);
1035 
1036         /*
1037          * If no block arg, or block arg == 0 or 1, use the FADT-defined
1038          * GPE blocks.
1039          */
1040         if (block_arg) {
1041                 block_number = strtoul(block_arg, NULL, 0);
1042                 if (block_number == 1) {
1043                         block_number = 0;
1044                 }
1045         }
1046 
1047         gpe_event_info =
1048             acpi_ev_get_gpe_event_info(ACPI_TO_POINTER(block_number),
1049                                        gpe_number);
1050         if (!gpe_event_info) {
1051                 acpi_os_printf("Invalid GPE\n");
1052                 return;
1053         }
1054 
1055         (void)acpi_ev_gpe_dispatch(NULL, gpe_event_info, gpe_number);
1056 }
1057 
1058 /*******************************************************************************
1059  *
1060  * FUNCTION:    acpi_db_generate_sci
1061  *
1062  * PARAMETERS:  None
1063  *
1064  * RETURN:      None
1065  *
1066  * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch.
1067  *
1068  ******************************************************************************/
1069 
1070 void acpi_db_generate_sci(void)
1071 {
1072         acpi_ev_sci_dispatch();
1073 }
1074 
1075 #endif                          /* !ACPI_REDUCED_HARDWARE */
1076 
1077 /*******************************************************************************
1078  *
1079  * FUNCTION:    acpi_db_trace
1080  *
1081  * PARAMETERS:  enable_arg          - ENABLE/AML to enable tracer
1082  *                                    DISABLE to disable tracer
1083  *              method_arg          - Method to trace
1084  *              once_arg            - Whether trace once
1085  *
1086  * RETURN:      None
1087  *
1088  * DESCRIPTION: Control method tracing facility
1089  *
1090  ******************************************************************************/
1091 
1092 void acpi_db_trace(char *enable_arg, char *method_arg, char *once_arg)
1093 {
1094         u32 debug_level = 0;
1095         u32 debug_layer = 0;
1096         u32 flags = 0;
1097 
1098         acpi_ut_strupr(enable_arg);
1099         acpi_ut_strupr(once_arg);
1100 
1101         if (method_arg) {
1102                 if (acpi_db_trace_method_name) {
1103                         ACPI_FREE(acpi_db_trace_method_name);
1104                         acpi_db_trace_method_name = NULL;
1105                 }
1106 
1107                 acpi_db_trace_method_name =
1108                     ACPI_ALLOCATE(strlen(method_arg) + 1);
1109                 if (!acpi_db_trace_method_name) {
1110                         acpi_os_printf("Failed to allocate method name (%s)\n",
1111                                        method_arg);
1112                         return;
1113                 }
1114 
1115                 strcpy(acpi_db_trace_method_name, method_arg);
1116         }
1117 
1118         if (!strcmp(enable_arg, "ENABLE") ||
1119             !strcmp(enable_arg, "METHOD") || !strcmp(enable_arg, "OPCODE")) {
1120                 if (!strcmp(enable_arg, "ENABLE")) {
1121 
1122                         /* Inherit current console settings */
1123 
1124                         debug_level = acpi_gbl_db_console_debug_level;
1125                         debug_layer = acpi_dbg_layer;
1126                 } else {
1127                         /* Restrict console output to trace points only */
1128 
1129                         debug_level = ACPI_LV_TRACE_POINT;
1130                         debug_layer = ACPI_EXECUTER;
1131                 }
1132 
1133                 flags = ACPI_TRACE_ENABLED;
1134 
1135                 if (!strcmp(enable_arg, "OPCODE")) {
1136                         flags |= ACPI_TRACE_OPCODE;
1137                 }
1138 
1139                 if (once_arg && !strcmp(once_arg, "ONCE")) {
1140                         flags |= ACPI_TRACE_ONESHOT;
1141                 }
1142         }
1143 
1144         (void)acpi_debug_trace(acpi_db_trace_method_name,
1145                                debug_level, debug_layer, flags);
1146 }

/* [<][>][^][v][top][bottom][index][help] */