Subversion Repositories Kolibri OS

Rev

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

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: dbstats - Generation and display of ACPI table statistics
  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 "acdebug.h"
  47. #include "acnamesp.h"
  48.  
  49. #define _COMPONENT          ACPI_CA_DEBUGGER
  50. ACPI_MODULE_NAME("dbstats")
  51.  
  52. /* Local prototypes */
  53. static void acpi_db_count_namespace_objects(void);
  54.  
  55. static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc);
  56.  
  57. static acpi_status
  58. acpi_db_classify_one_object(acpi_handle obj_handle,
  59.                             u32 nesting_level,
  60.                             void *context, void **return_value);
  61.  
  62. #if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
  63. static void acpi_db_list_info(struct acpi_memory_list *list);
  64. #endif
  65.  
  66. /*
  67.  * Statistics subcommands
  68.  */
  69. static struct acpi_db_argument_info acpi_db_stat_types[] = {
  70.         {"ALLOCATIONS"},
  71.         {"OBJECTS"},
  72.         {"MEMORY"},
  73.         {"MISC"},
  74.         {"TABLES"},
  75.         {"SIZES"},
  76.         {"STACK"},
  77.         {NULL}                  /* Must be null terminated */
  78. };
  79.  
  80. #define CMD_STAT_ALLOCATIONS     0
  81. #define CMD_STAT_OBJECTS         1
  82. #define CMD_STAT_MEMORY          2
  83. #define CMD_STAT_MISC            3
  84. #define CMD_STAT_TABLES          4
  85. #define CMD_STAT_SIZES           5
  86. #define CMD_STAT_STACK           6
  87.  
  88. #if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
  89. /*******************************************************************************
  90.  *
  91.  * FUNCTION:    acpi_db_list_info
  92.  *
  93.  * PARAMETERS:  list            - Memory list/cache to be displayed
  94.  *
  95.  * RETURN:      None
  96.  *
  97.  * DESCRIPTION: Display information about the input memory list or cache.
  98.  *
  99.  ******************************************************************************/
  100.  
  101. static void acpi_db_list_info(struct acpi_memory_list *list)
  102. {
  103. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  104.         u32 outstanding;
  105. #endif
  106.  
  107.         acpi_os_printf("\n%s\n", list->list_name);
  108.  
  109.         /* max_depth > 0 indicates a cache object */
  110.  
  111.         if (list->max_depth > 0) {
  112.                 acpi_os_printf
  113.                     ("    Cache: [Depth    MaxD Avail  Size]                "
  114.                      "%8.2X %8.2X %8.2X %8.2X\n", list->current_depth,
  115.                      list->max_depth, list->max_depth - list->current_depth,
  116.                      (list->current_depth * list->object_size));
  117.         }
  118. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  119.         if (list->max_depth > 0) {
  120.                 acpi_os_printf
  121.                     ("    Cache: [Requests Hits Misses ObjSize]             "
  122.                      "%8.2X %8.2X %8.2X %8.2X\n", list->requests, list->hits,
  123.                      list->requests - list->hits, list->object_size);
  124.         }
  125.  
  126.         outstanding = acpi_db_get_cache_info(list);
  127.  
  128.         if (list->object_size) {
  129.                 acpi_os_printf
  130.                     ("    Mem:   [Alloc    Free Max    CurSize Outstanding] "
  131.                      "%8.2X %8.2X %8.2X %8.2X %8.2X\n", list->total_allocated,
  132.                      list->total_freed, list->max_occupied,
  133.                      outstanding * list->object_size, outstanding);
  134.         } else {
  135.                 acpi_os_printf
  136.                     ("    Mem:   [Alloc Free Max CurSize Outstanding Total] "
  137.                      "%8.2X %8.2X %8.2X %8.2X %8.2X %8.2X\n",
  138.                      list->total_allocated, list->total_freed,
  139.                      list->max_occupied, list->current_total_size, outstanding,
  140.                      list->total_size);
  141.         }
  142. #endif
  143. }
  144. #endif
  145.  
  146. /*******************************************************************************
  147.  *
  148.  * FUNCTION:    acpi_db_enumerate_object
  149.  *
  150.  * PARAMETERS:  obj_desc            - Object to be counted
  151.  *
  152.  * RETURN:      None
  153.  *
  154.  * DESCRIPTION: Add this object to the global counts, by object type.
  155.  *              Limited recursion handles subobjects and packages, and this
  156.  *              is probably acceptable within the AML debugger only.
  157.  *
  158.  ******************************************************************************/
  159.  
  160. static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc)
  161. {
  162.         u32 i;
  163.  
  164.         if (!obj_desc) {
  165.                 return;
  166.         }
  167.  
  168.         /* Enumerate this object first */
  169.  
  170.         acpi_gbl_num_objects++;
  171.  
  172.         if (obj_desc->common.type > ACPI_TYPE_NS_NODE_MAX) {
  173.                 acpi_gbl_obj_type_count_misc++;
  174.         } else {
  175.                 acpi_gbl_obj_type_count[obj_desc->common.type]++;
  176.         }
  177.  
  178.         /* Count the sub-objects */
  179.  
  180.         switch (obj_desc->common.type) {
  181.         case ACPI_TYPE_PACKAGE:
  182.  
  183.                 for (i = 0; i < obj_desc->package.count; i++) {
  184.                         acpi_db_enumerate_object(obj_desc->package.elements[i]);
  185.                 }
  186.                 break;
  187.  
  188.         case ACPI_TYPE_DEVICE:
  189.  
  190.                 acpi_db_enumerate_object(obj_desc->device.notify_list[0]);
  191.                 acpi_db_enumerate_object(obj_desc->device.notify_list[1]);
  192.                 acpi_db_enumerate_object(obj_desc->device.handler);
  193.                 break;
  194.  
  195.         case ACPI_TYPE_BUFFER_FIELD:
  196.  
  197.                 if (acpi_ns_get_secondary_object(obj_desc)) {
  198.                         acpi_gbl_obj_type_count[ACPI_TYPE_BUFFER_FIELD]++;
  199.                 }
  200.                 break;
  201.  
  202.         case ACPI_TYPE_REGION:
  203.  
  204.                 acpi_gbl_obj_type_count[ACPI_TYPE_LOCAL_REGION_FIELD]++;
  205.                 acpi_db_enumerate_object(obj_desc->region.handler);
  206.                 break;
  207.  
  208.         case ACPI_TYPE_POWER:
  209.  
  210.                 acpi_db_enumerate_object(obj_desc->power_resource.
  211.                                          notify_list[0]);
  212.                 acpi_db_enumerate_object(obj_desc->power_resource.
  213.                                          notify_list[1]);
  214.                 break;
  215.  
  216.         case ACPI_TYPE_PROCESSOR:
  217.  
  218.                 acpi_db_enumerate_object(obj_desc->processor.notify_list[0]);
  219.                 acpi_db_enumerate_object(obj_desc->processor.notify_list[1]);
  220.                 acpi_db_enumerate_object(obj_desc->processor.handler);
  221.                 break;
  222.  
  223.         case ACPI_TYPE_THERMAL:
  224.  
  225.                 acpi_db_enumerate_object(obj_desc->thermal_zone.notify_list[0]);
  226.                 acpi_db_enumerate_object(obj_desc->thermal_zone.notify_list[1]);
  227.                 acpi_db_enumerate_object(obj_desc->thermal_zone.handler);
  228.                 break;
  229.  
  230.         default:
  231.  
  232.                 break;
  233.         }
  234. }
  235.  
  236. /*******************************************************************************
  237.  *
  238.  * FUNCTION:    acpi_db_classify_one_object
  239.  *
  240.  * PARAMETERS:  Callback for walk_namespace
  241.  *
  242.  * RETURN:      Status
  243.  *
  244.  * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and
  245.  *              the parent namespace node.
  246.  *
  247.  ******************************************************************************/
  248.  
  249. static acpi_status
  250. acpi_db_classify_one_object(acpi_handle obj_handle,
  251.                             u32 nesting_level,
  252.                             void *context, void **return_value)
  253. {
  254.         struct acpi_namespace_node *node;
  255.         union acpi_operand_object *obj_desc;
  256.         u32 type;
  257.  
  258.         acpi_gbl_num_nodes++;
  259.  
  260.         node = (struct acpi_namespace_node *)obj_handle;
  261.         obj_desc = acpi_ns_get_attached_object(node);
  262.  
  263.         acpi_db_enumerate_object(obj_desc);
  264.  
  265.         type = node->type;
  266.         if (type > ACPI_TYPE_NS_NODE_MAX) {
  267.                 acpi_gbl_node_type_count_misc++;
  268.         } else {
  269.                 acpi_gbl_node_type_count[type]++;
  270.         }
  271.  
  272.         return (AE_OK);
  273.  
  274. #ifdef ACPI_FUTURE_IMPLEMENTATION
  275.  
  276.         /* TBD: These need to be counted during the initial parsing phase */
  277.  
  278.         if (acpi_ps_is_named_op(op->opcode)) {
  279.                 num_nodes++;
  280.         }
  281.  
  282.         if (is_method) {
  283.                 num_method_elements++;
  284.         }
  285.  
  286.         num_grammar_elements++;
  287.         op = acpi_ps_get_depth_next(root, op);
  288.  
  289.         size_of_parse_tree = (num_grammar_elements - num_method_elements) *
  290.             (u32)sizeof(union acpi_parse_object);
  291.         size_of_method_trees =
  292.             num_method_elements * (u32)sizeof(union acpi_parse_object);
  293.         size_of_node_entries =
  294.             num_nodes * (u32)sizeof(struct acpi_namespace_node);
  295.         size_of_acpi_objects =
  296.             num_nodes * (u32)sizeof(union acpi_operand_object);
  297. #endif
  298. }
  299.  
  300. /*******************************************************************************
  301.  *
  302.  * FUNCTION:    acpi_db_count_namespace_objects
  303.  *
  304.  * PARAMETERS:  None
  305.  *
  306.  * RETURN:      None
  307.  *
  308.  * DESCRIPTION: Count and classify the entire namespace, including all
  309.  *              namespace nodes and attached objects.
  310.  *
  311.  ******************************************************************************/
  312.  
  313. static void acpi_db_count_namespace_objects(void)
  314. {
  315.         u32 i;
  316.  
  317.         acpi_gbl_num_nodes = 0;
  318.         acpi_gbl_num_objects = 0;
  319.  
  320.         acpi_gbl_obj_type_count_misc = 0;
  321.         for (i = 0; i < (ACPI_TYPE_NS_NODE_MAX - 1); i++) {
  322.                 acpi_gbl_obj_type_count[i] = 0;
  323.                 acpi_gbl_node_type_count[i] = 0;
  324.         }
  325.  
  326.         (void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
  327.                                      ACPI_UINT32_MAX, FALSE,
  328.                                      acpi_db_classify_one_object, NULL, NULL,
  329.                                      NULL);
  330. }
  331.  
  332. /*******************************************************************************
  333.  *
  334.  * FUNCTION:    acpi_db_display_statistics
  335.  *
  336.  * PARAMETERS:  type_arg        - Subcommand
  337.  *
  338.  * RETURN:      Status
  339.  *
  340.  * DESCRIPTION: Display various statistics
  341.  *
  342.  ******************************************************************************/
  343.  
  344. acpi_status acpi_db_display_statistics(char *type_arg)
  345. {
  346.         u32 i;
  347.         u32 temp;
  348.  
  349.         acpi_ut_strupr(type_arg);
  350.         temp = acpi_db_match_argument(type_arg, acpi_db_stat_types);
  351.         if (temp == ACPI_TYPE_NOT_FOUND) {
  352.                 acpi_os_printf("Invalid or unsupported argument\n");
  353.                 return (AE_OK);
  354.         }
  355.  
  356.         switch (temp) {
  357.         case CMD_STAT_ALLOCATIONS:
  358.  
  359. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  360.                 acpi_ut_dump_allocation_info();
  361. #endif
  362.                 break;
  363.  
  364.         case CMD_STAT_TABLES:
  365.  
  366.                 acpi_os_printf("ACPI Table Information (not implemented):\n\n");
  367.                 break;
  368.  
  369.         case CMD_STAT_OBJECTS:
  370.  
  371.                 acpi_db_count_namespace_objects();
  372.  
  373.                 acpi_os_printf
  374.                     ("\nObjects defined in the current namespace:\n\n");
  375.  
  376.                 acpi_os_printf("%16.16s %10.10s %10.10s\n",
  377.                                "ACPI_TYPE", "NODES", "OBJECTS");
  378.  
  379.                 for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++) {
  380.                         acpi_os_printf("%16.16s % 10ld% 10ld\n",
  381.                                        acpi_ut_get_type_name(i),
  382.                                        acpi_gbl_node_type_count[i],
  383.                                        acpi_gbl_obj_type_count[i]);
  384.                 }
  385.                 acpi_os_printf("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
  386.                                acpi_gbl_node_type_count_misc,
  387.                                acpi_gbl_obj_type_count_misc);
  388.  
  389.                 acpi_os_printf("%16.16s % 10ld% 10ld\n", "TOTALS:",
  390.                                acpi_gbl_num_nodes, acpi_gbl_num_objects);
  391.                 break;
  392.  
  393.         case CMD_STAT_MEMORY:
  394.  
  395. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  396.                 acpi_os_printf
  397.                     ("\n----Object Statistics (all in hex)---------\n");
  398.  
  399.                 acpi_db_list_info(acpi_gbl_global_list);
  400.                 acpi_db_list_info(acpi_gbl_ns_node_list);
  401. #endif
  402.  
  403. #ifdef ACPI_USE_LOCAL_CACHE
  404.                 acpi_os_printf
  405.                     ("\n----Cache Statistics (all in hex)---------\n");
  406.                 acpi_db_list_info(acpi_gbl_operand_cache);
  407.                 acpi_db_list_info(acpi_gbl_ps_node_cache);
  408.                 acpi_db_list_info(acpi_gbl_ps_node_ext_cache);
  409.                 acpi_db_list_info(acpi_gbl_state_cache);
  410. #endif
  411.  
  412.                 break;
  413.  
  414.         case CMD_STAT_MISC:
  415.  
  416.                 acpi_os_printf("\nMiscellaneous Statistics:\n\n");
  417.                 acpi_os_printf("Calls to AcpiPsFind:.. ........% 7ld\n",
  418.                                acpi_gbl_ps_find_count);
  419.                 acpi_os_printf("Calls to AcpiNsLookup:..........% 7ld\n",
  420.                                acpi_gbl_ns_lookup_count);
  421.  
  422.                 acpi_os_printf("\n");
  423.  
  424.                 acpi_os_printf("Mutex usage:\n\n");
  425.                 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
  426.                         acpi_os_printf("%-28s:     % 7ld\n",
  427.                                        acpi_ut_get_mutex_name(i),
  428.                                        acpi_gbl_mutex_info[i].use_count);
  429.                 }
  430.                 break;
  431.  
  432.         case CMD_STAT_SIZES:
  433.  
  434.                 acpi_os_printf("\nInternal object sizes:\n\n");
  435.  
  436.                 acpi_os_printf("Common         %3d\n",
  437.                                sizeof(struct acpi_object_common));
  438.                 acpi_os_printf("Number         %3d\n",
  439.                                sizeof(struct acpi_object_integer));
  440.                 acpi_os_printf("String         %3d\n",
  441.                                sizeof(struct acpi_object_string));
  442.                 acpi_os_printf("Buffer         %3d\n",
  443.                                sizeof(struct acpi_object_buffer));
  444.                 acpi_os_printf("Package        %3d\n",
  445.                                sizeof(struct acpi_object_package));
  446.                 acpi_os_printf("BufferField    %3d\n",
  447.                                sizeof(struct acpi_object_buffer_field));
  448.                 acpi_os_printf("Device         %3d\n",
  449.                                sizeof(struct acpi_object_device));
  450.                 acpi_os_printf("Event          %3d\n",
  451.                                sizeof(struct acpi_object_event));
  452.                 acpi_os_printf("Method         %3d\n",
  453.                                sizeof(struct acpi_object_method));
  454.                 acpi_os_printf("Mutex          %3d\n",
  455.                                sizeof(struct acpi_object_mutex));
  456.                 acpi_os_printf("Region         %3d\n",
  457.                                sizeof(struct acpi_object_region));
  458.                 acpi_os_printf("PowerResource  %3d\n",
  459.                                sizeof(struct acpi_object_power_resource));
  460.                 acpi_os_printf("Processor      %3d\n",
  461.                                sizeof(struct acpi_object_processor));
  462.                 acpi_os_printf("ThermalZone    %3d\n",
  463.                                sizeof(struct acpi_object_thermal_zone));
  464.                 acpi_os_printf("RegionField    %3d\n",
  465.                                sizeof(struct acpi_object_region_field));
  466.                 acpi_os_printf("BankField      %3d\n",
  467.                                sizeof(struct acpi_object_bank_field));
  468.                 acpi_os_printf("IndexField     %3d\n",
  469.                                sizeof(struct acpi_object_index_field));
  470.                 acpi_os_printf("Reference      %3d\n",
  471.                                sizeof(struct acpi_object_reference));
  472.                 acpi_os_printf("Notify         %3d\n",
  473.                                sizeof(struct acpi_object_notify_handler));
  474.                 acpi_os_printf("AddressSpace   %3d\n",
  475.                                sizeof(struct acpi_object_addr_handler));
  476.                 acpi_os_printf("Extra          %3d\n",
  477.                                sizeof(struct acpi_object_extra));
  478.                 acpi_os_printf("Data           %3d\n",
  479.                                sizeof(struct acpi_object_data));
  480.  
  481.                 acpi_os_printf("\n");
  482.  
  483.                 acpi_os_printf("ParseObject    %3d\n",
  484.                                sizeof(struct acpi_parse_obj_common));
  485.                 acpi_os_printf("ParseObjectNamed %3d\n",
  486.                                sizeof(struct acpi_parse_obj_named));
  487.                 acpi_os_printf("ParseObjectAsl %3d\n",
  488.                                sizeof(struct acpi_parse_obj_asl));
  489.                 acpi_os_printf("OperandObject  %3d\n",
  490.                                sizeof(union acpi_operand_object));
  491.                 acpi_os_printf("NamespaceNode  %3d\n",
  492.                                sizeof(struct acpi_namespace_node));
  493.                 acpi_os_printf("AcpiObject     %3d\n",
  494.                                sizeof(union acpi_object));
  495.  
  496.                 acpi_os_printf("\n");
  497.  
  498.                 acpi_os_printf("Generic State  %3d\n",
  499.                                sizeof(union acpi_generic_state));
  500.                 acpi_os_printf("Common State   %3d\n",
  501.                                sizeof(struct acpi_common_state));
  502.                 acpi_os_printf("Control State  %3d\n",
  503.                                sizeof(struct acpi_control_state));
  504.                 acpi_os_printf("Update State   %3d\n",
  505.                                sizeof(struct acpi_update_state));
  506.                 acpi_os_printf("Scope State    %3d\n",
  507.                                sizeof(struct acpi_scope_state));
  508.                 acpi_os_printf("Parse Scope    %3d\n",
  509.                                sizeof(struct acpi_pscope_state));
  510.                 acpi_os_printf("Package State  %3d\n",
  511.                                sizeof(struct acpi_pkg_state));
  512.                 acpi_os_printf("Thread State   %3d\n",
  513.                                sizeof(struct acpi_thread_state));
  514.                 acpi_os_printf("Result Values  %3d\n",
  515.                                sizeof(struct acpi_result_values));
  516.                 acpi_os_printf("Notify Info    %3d\n",
  517.                                sizeof(struct acpi_notify_info));
  518.                 break;
  519.  
  520.         case CMD_STAT_STACK:
  521. #if defined(ACPI_DEBUG_OUTPUT)
  522.  
  523.                 temp =
  524.                     (u32)ACPI_PTR_DIFF(acpi_gbl_entry_stack_pointer,
  525.                                        acpi_gbl_lowest_stack_pointer);
  526.  
  527.                 acpi_os_printf("\nSubsystem Stack Usage:\n\n");
  528.                 acpi_os_printf("Entry Stack Pointer        %p\n",
  529.                                acpi_gbl_entry_stack_pointer);
  530.                 acpi_os_printf("Lowest Stack Pointer       %p\n",
  531.                                acpi_gbl_lowest_stack_pointer);
  532.                 acpi_os_printf("Stack Use                  %X (%u)\n", temp,
  533.                                temp);
  534.                 acpi_os_printf("Deepest Procedure Nesting  %u\n",
  535.                                acpi_gbl_deepest_nesting);
  536. #endif
  537.                 break;
  538.  
  539.         default:
  540.  
  541.                 break;
  542.         }
  543.  
  544.         acpi_os_printf("\n");
  545.         return (AE_OK);
  546. }
  547.