Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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