Subversion Repositories Kolibri OS

Rev

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

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: dbutils - AML debugger utilities
  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 "acnamesp.h"
  47. #include "acdebug.h"
  48.  
  49. #define _COMPONENT          ACPI_CA_DEBUGGER
  50. ACPI_MODULE_NAME("dbutils")
  51.  
  52. /* Local prototypes */
  53. #ifdef ACPI_OBSOLETE_FUNCTIONS
  54. acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root);
  55.  
  56. void acpi_db_dump_buffer(u32 address);
  57. #endif
  58.  
  59. static char *gbl_hex_to_ascii = "0123456789ABCDEF";
  60.  
  61. /*******************************************************************************
  62.  *
  63.  * FUNCTION:    acpi_db_match_argument
  64.  *
  65.  * PARAMETERS:  user_argument           - User command line
  66.  *              arguments               - Array of commands to match against
  67.  *
  68.  * RETURN:      Index into command array or ACPI_TYPE_NOT_FOUND if not found
  69.  *
  70.  * DESCRIPTION: Search command array for a command match
  71.  *
  72.  ******************************************************************************/
  73.  
  74. acpi_object_type
  75. acpi_db_match_argument(char *user_argument,
  76.                        struct acpi_db_argument_info *arguments)
  77. {
  78.         u32 i;
  79.  
  80.         if (!user_argument || user_argument[0] == 0) {
  81.                 return (ACPI_TYPE_NOT_FOUND);
  82.         }
  83.  
  84.         for (i = 0; arguments[i].name; i++) {
  85.                 if (strstr(arguments[i].name, user_argument) ==
  86.                     arguments[i].name) {
  87.                         return (i);
  88.                 }
  89.         }
  90.  
  91.         /* Argument not recognized */
  92.  
  93.         return (ACPI_TYPE_NOT_FOUND);
  94. }
  95.  
  96. /*******************************************************************************
  97.  *
  98.  * FUNCTION:    acpi_db_set_output_destination
  99.  *
  100.  * PARAMETERS:  output_flags        - Current flags word
  101.  *
  102.  * RETURN:      None
  103.  *
  104.  * DESCRIPTION: Set the current destination for debugger output. Also sets
  105.  *              the debug output level accordingly.
  106.  *
  107.  ******************************************************************************/
  108.  
  109. void acpi_db_set_output_destination(u32 output_flags)
  110. {
  111.  
  112.         acpi_gbl_db_output_flags = (u8)output_flags;
  113.  
  114.         if ((output_flags & ACPI_DB_REDIRECTABLE_OUTPUT) &&
  115.             acpi_gbl_db_output_to_file) {
  116.                 acpi_dbg_level = acpi_gbl_db_debug_level;
  117.         } else {
  118.                 acpi_dbg_level = acpi_gbl_db_console_debug_level;
  119.         }
  120. }
  121.  
  122. /*******************************************************************************
  123.  *
  124.  * FUNCTION:    acpi_db_dump_external_object
  125.  *
  126.  * PARAMETERS:  obj_desc        - External ACPI object to dump
  127.  *              level           - Nesting level.
  128.  *
  129.  * RETURN:      None
  130.  *
  131.  * DESCRIPTION: Dump the contents of an ACPI external object
  132.  *
  133.  ******************************************************************************/
  134.  
  135. void acpi_db_dump_external_object(union acpi_object *obj_desc, u32 level)
  136. {
  137.         u32 i;
  138.  
  139.         if (!obj_desc) {
  140.                 acpi_os_printf("[Null Object]\n");
  141.                 return;
  142.         }
  143.  
  144.         for (i = 0; i < level; i++) {
  145.                 acpi_os_printf(" ");
  146.         }
  147.  
  148.         switch (obj_desc->type) {
  149.         case ACPI_TYPE_ANY:
  150.  
  151.                 acpi_os_printf("[Null Object] (Type=0)\n");
  152.                 break;
  153.  
  154.         case ACPI_TYPE_INTEGER:
  155.  
  156.                 acpi_os_printf("[Integer] = %8.8X%8.8X\n",
  157.                                ACPI_FORMAT_UINT64(obj_desc->integer.value));
  158.                 break;
  159.  
  160.         case ACPI_TYPE_STRING:
  161.  
  162.                 acpi_os_printf("[String] Length %.2X = ",
  163.                                obj_desc->string.length);
  164.                 acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX);
  165.                 acpi_os_printf("\n");
  166.                 break;
  167.  
  168.         case ACPI_TYPE_BUFFER:
  169.  
  170.                 acpi_os_printf("[Buffer] Length %.2X = ",
  171.                                obj_desc->buffer.length);
  172.                 if (obj_desc->buffer.length) {
  173.                         if (obj_desc->buffer.length > 16) {
  174.                                 acpi_os_printf("\n");
  175.                         }
  176.                         acpi_ut_debug_dump_buffer(ACPI_CAST_PTR
  177.                                                   (u8,
  178.                                                    obj_desc->buffer.pointer),
  179.                                                   obj_desc->buffer.length,
  180.                                                   DB_BYTE_DISPLAY, _COMPONENT);
  181.                 } else {
  182.                         acpi_os_printf("\n");
  183.                 }
  184.                 break;
  185.  
  186.         case ACPI_TYPE_PACKAGE:
  187.  
  188.                 acpi_os_printf("[Package] Contains %u Elements:\n",
  189.                                obj_desc->package.count);
  190.  
  191.                 for (i = 0; i < obj_desc->package.count; i++) {
  192.                         acpi_db_dump_external_object(&obj_desc->package.
  193.                                                      elements[i], level + 1);
  194.                 }
  195.                 break;
  196.  
  197.         case ACPI_TYPE_LOCAL_REFERENCE:
  198.  
  199.                 acpi_os_printf("[Object Reference] = ");
  200.                 acpi_db_display_internal_object(obj_desc->reference.handle,
  201.                                                 NULL);
  202.                 break;
  203.  
  204.         case ACPI_TYPE_PROCESSOR:
  205.  
  206.                 acpi_os_printf("[Processor]\n");
  207.                 break;
  208.  
  209.         case ACPI_TYPE_POWER:
  210.  
  211.                 acpi_os_printf("[Power Resource]\n");
  212.                 break;
  213.  
  214.         default:
  215.  
  216.                 acpi_os_printf("[Unknown Type] %X\n", obj_desc->type);
  217.                 break;
  218.         }
  219. }
  220.  
  221. /*******************************************************************************
  222.  *
  223.  * FUNCTION:    acpi_db_prep_namestring
  224.  *
  225.  * PARAMETERS:  name            - String to prepare
  226.  *
  227.  * RETURN:      None
  228.  *
  229.  * DESCRIPTION: Translate all forward slashes and dots to backslashes.
  230.  *
  231.  ******************************************************************************/
  232.  
  233. void acpi_db_prep_namestring(char *name)
  234. {
  235.  
  236.         if (!name) {
  237.                 return;
  238.         }
  239.  
  240.         acpi_ut_strupr(name);
  241.  
  242.         /* Convert a leading forward slash to a backslash */
  243.  
  244.         if (*name == '/') {
  245.                 *name = '\\';
  246.         }
  247.  
  248.         /* Ignore a leading backslash, this is the root prefix */
  249.  
  250.         if (ACPI_IS_ROOT_PREFIX(*name)) {
  251.                 name++;
  252.         }
  253.  
  254.         /* Convert all slash path separators to dots */
  255.  
  256.         while (*name) {
  257.                 if ((*name == '/') || (*name == '\\')) {
  258.                         *name = '.';
  259.                 }
  260.  
  261.                 name++;
  262.         }
  263. }
  264.  
  265. /*******************************************************************************
  266.  *
  267.  * FUNCTION:    acpi_db_local_ns_lookup
  268.  *
  269.  * PARAMETERS:  name            - Name to lookup
  270.  *
  271.  * RETURN:      Pointer to a namespace node, null on failure
  272.  *
  273.  * DESCRIPTION: Lookup a name in the ACPI namespace
  274.  *
  275.  * Note: Currently begins search from the root. Could be enhanced to use
  276.  * the current prefix (scope) node as the search beginning point.
  277.  *
  278.  ******************************************************************************/
  279.  
  280. struct acpi_namespace_node *acpi_db_local_ns_lookup(char *name)
  281. {
  282.         char *internal_path;
  283.         acpi_status status;
  284.         struct acpi_namespace_node *node = NULL;
  285.  
  286.         acpi_db_prep_namestring(name);
  287.  
  288.         /* Build an internal namestring */
  289.  
  290.         status = acpi_ns_internalize_name(name, &internal_path);
  291.         if (ACPI_FAILURE(status)) {
  292.                 acpi_os_printf("Invalid namestring: %s\n", name);
  293.                 return (NULL);
  294.         }
  295.  
  296.         /*
  297.          * Lookup the name.
  298.          * (Uses root node as the search starting point)
  299.          */
  300.         status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY,
  301.                                 ACPI_IMODE_EXECUTE,
  302.                                 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
  303.                                 NULL, &node);
  304.         if (ACPI_FAILURE(status)) {
  305.                 acpi_os_printf("Could not locate name: %s, %s\n",
  306.                                name, acpi_format_exception(status));
  307.         }
  308.  
  309.         ACPI_FREE(internal_path);
  310.         return (node);
  311. }
  312.  
  313. /*******************************************************************************
  314.  *
  315.  * FUNCTION:    acpi_db_uint32_to_hex_string
  316.  *
  317.  * PARAMETERS:  value           - The value to be converted to string
  318.  *              buffer          - Buffer for result (not less than 11 bytes)
  319.  *
  320.  * RETURN:      None
  321.  *
  322.  * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image
  323.  *
  324.  * NOTE: It is the caller's responsibility to ensure that the length of buffer
  325.  *       is sufficient.
  326.  *
  327.  ******************************************************************************/
  328.  
  329. void acpi_db_uint32_to_hex_string(u32 value, char *buffer)
  330. {
  331.         int i;
  332.  
  333.         if (value == 0) {
  334.                 strcpy(buffer, "0");
  335.                 return;
  336.         }
  337.  
  338.         buffer[8] = '\0';
  339.  
  340.         for (i = 7; i >= 0; i--) {
  341.                 buffer[i] = gbl_hex_to_ascii[value & 0x0F];
  342.                 value = value >> 4;
  343.         }
  344. }
  345.  
  346. #ifdef ACPI_OBSOLETE_FUNCTIONS
  347. /*******************************************************************************
  348.  *
  349.  * FUNCTION:    acpi_db_second_pass_parse
  350.  *
  351.  * PARAMETERS:  root            - Root of the parse tree
  352.  *
  353.  * RETURN:      Status
  354.  *
  355.  * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until
  356.  *              second pass to parse the control methods
  357.  *
  358.  ******************************************************************************/
  359.  
  360. acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root)
  361. {
  362.         union acpi_parse_object *op = root;
  363.         union acpi_parse_object *method;
  364.         union acpi_parse_object *search_op;
  365.         union acpi_parse_object *start_op;
  366.         acpi_status status = AE_OK;
  367.         u32 base_aml_offset;
  368.         struct acpi_walk_state *walk_state;
  369.  
  370.         ACPI_FUNCTION_ENTRY();
  371.  
  372.         acpi_os_printf("Pass two parse ....\n");
  373.  
  374.         while (op) {
  375.                 if (op->common.aml_opcode == AML_METHOD_OP) {
  376.                         method = op;
  377.  
  378.                         /* Create a new walk state for the parse */
  379.  
  380.                         walk_state =
  381.                             acpi_ds_create_walk_state(0, NULL, NULL, NULL);
  382.                         if (!walk_state) {
  383.                                 return (AE_NO_MEMORY);
  384.                         }
  385.  
  386.                         /* Init the Walk State */
  387.  
  388.                         walk_state->parser_state.aml =
  389.                             walk_state->parser_state.aml_start =
  390.                             method->named.data;
  391.                         walk_state->parser_state.aml_end =
  392.                             walk_state->parser_state.pkg_end =
  393.                             method->named.data + method->named.length;
  394.                         walk_state->parser_state.start_scope = op;
  395.  
  396.                         walk_state->descending_callback =
  397.                             acpi_ds_load1_begin_op;
  398.                         walk_state->ascending_callback = acpi_ds_load1_end_op;
  399.  
  400.                         /* Perform the AML parse */
  401.  
  402.                         status = acpi_ps_parse_aml(walk_state);
  403.  
  404.                         base_aml_offset =
  405.                             (method->common.value.arg)->common.aml_offset + 1;
  406.                         start_op = (method->common.value.arg)->common.next;
  407.                         search_op = start_op;
  408.  
  409.                         while (search_op) {
  410.                                 search_op->common.aml_offset += base_aml_offset;
  411.                                 search_op =
  412.                                     acpi_ps_get_depth_next(start_op, search_op);
  413.                         }
  414.                 }
  415.  
  416.                 if (op->common.aml_opcode == AML_REGION_OP) {
  417.  
  418.                         /* TBD: [Investigate] this isn't quite the right thing to do! */
  419.                         /*
  420.                          *
  421.                          * Method = (ACPI_DEFERRED_OP *) Op;
  422.                          * Status = acpi_ps_parse_aml (Op, Method->Body, Method->body_length);
  423.                          */
  424.                 }
  425.  
  426.                 if (ACPI_FAILURE(status)) {
  427.                         break;
  428.                 }
  429.  
  430.                 op = acpi_ps_get_depth_next(root, op);
  431.         }
  432.  
  433.         return (status);
  434. }
  435.  
  436. /*******************************************************************************
  437.  *
  438.  * FUNCTION:    acpi_db_dump_buffer
  439.  *
  440.  * PARAMETERS:  address             - Pointer to the buffer
  441.  *
  442.  * RETURN:      None
  443.  *
  444.  * DESCRIPTION: Print a portion of a buffer
  445.  *
  446.  ******************************************************************************/
  447.  
  448. void acpi_db_dump_buffer(u32 address)
  449. {
  450.  
  451.         acpi_os_printf("\nLocation %X:\n", address);
  452.  
  453.         acpi_dbg_level |= ACPI_LV_TABLES;
  454.         acpi_ut_debug_dump_buffer(ACPI_TO_POINTER(address), 64, DB_BYTE_DISPLAY,
  455.                                   ACPI_UINT32_MAX);
  456. }
  457. #endif
  458.