1 /****************************************************************************** 2 * 3 * Module Name: dbhistry - debugger HISTORY command 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, 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 48 #define _COMPONENT ACPI_CA_DEBUGGER 49 ACPI_MODULE_NAME("dbhistry") 50 51 #define HI_NO_HISTORY 0 52 #define HI_RECORD_HISTORY 1 53 #define HISTORY_SIZE 40 54 typedef struct history_info { 55 char *command; 56 u32 cmd_num; 57 58 } HISTORY_INFO; 59 60 static HISTORY_INFO acpi_gbl_history_buffer[HISTORY_SIZE]; 61 static u16 acpi_gbl_lo_history = 0; 62 static u16 acpi_gbl_num_history = 0; 63 static u16 acpi_gbl_next_history_index = 0; 64 u32 acpi_gbl_next_cmd_num = 1; 65 66 /******************************************************************************* 67 * 68 * FUNCTION: acpi_db_add_to_history 69 * 70 * PARAMETERS: command_line - Command to add 71 * 72 * RETURN: None 73 * 74 * DESCRIPTION: Add a command line to the history buffer. 75 * 76 ******************************************************************************/ 77 78 void acpi_db_add_to_history(char *command_line) 79 { 80 u16 cmd_len; 81 u16 buffer_len; 82 83 /* Put command into the next available slot */ 84 85 cmd_len = (u16)strlen(command_line); 86 if (!cmd_len) { 87 return; 88 } 89 90 if (acpi_gbl_history_buffer[acpi_gbl_next_history_index].command != 91 NULL) { 92 buffer_len = 93 (u16) 94 strlen(acpi_gbl_history_buffer[acpi_gbl_next_history_index]. 95 command); 96 97 if (cmd_len > buffer_len) { 98 acpi_os_free(acpi_gbl_history_buffer 99 [acpi_gbl_next_history_index].command); 100 acpi_gbl_history_buffer[acpi_gbl_next_history_index]. 101 command = acpi_os_allocate(cmd_len + 1); 102 } 103 } else { 104 acpi_gbl_history_buffer[acpi_gbl_next_history_index].command = 105 acpi_os_allocate(cmd_len + 1); 106 } 107 108 strcpy(acpi_gbl_history_buffer[acpi_gbl_next_history_index].command, 109 command_line); 110 111 acpi_gbl_history_buffer[acpi_gbl_next_history_index].cmd_num = 112 acpi_gbl_next_cmd_num; 113 114 /* Adjust indexes */ 115 116 if ((acpi_gbl_num_history == HISTORY_SIZE) && 117 (acpi_gbl_next_history_index == acpi_gbl_lo_history)) { 118 acpi_gbl_lo_history++; 119 if (acpi_gbl_lo_history >= HISTORY_SIZE) { 120 acpi_gbl_lo_history = 0; 121 } 122 } 123 124 acpi_gbl_next_history_index++; 125 if (acpi_gbl_next_history_index >= HISTORY_SIZE) { 126 acpi_gbl_next_history_index = 0; 127 } 128 129 acpi_gbl_next_cmd_num++; 130 if (acpi_gbl_num_history < HISTORY_SIZE) { 131 acpi_gbl_num_history++; 132 } 133 } 134 135 /******************************************************************************* 136 * 137 * FUNCTION: acpi_db_display_history 138 * 139 * PARAMETERS: None 140 * 141 * RETURN: None 142 * 143 * DESCRIPTION: Display the contents of the history buffer 144 * 145 ******************************************************************************/ 146 147 void acpi_db_display_history(void) 148 { 149 u32 i; 150 u16 history_index; 151 152 history_index = acpi_gbl_lo_history; 153 154 /* Dump entire history buffer */ 155 156 for (i = 0; i < acpi_gbl_num_history; i++) { 157 if (acpi_gbl_history_buffer[history_index].command) { 158 acpi_os_printf("%3ld %s\n", 159 acpi_gbl_history_buffer[history_index]. 160 cmd_num, 161 acpi_gbl_history_buffer[history_index]. 162 command); 163 } 164 165 history_index++; 166 if (history_index >= HISTORY_SIZE) { 167 history_index = 0; 168 } 169 } 170 } 171 172 /******************************************************************************* 173 * 174 * FUNCTION: acpi_db_get_from_history 175 * 176 * PARAMETERS: command_num_arg - String containing the number of the 177 * command to be retrieved 178 * 179 * RETURN: Pointer to the retrieved command. Null on error. 180 * 181 * DESCRIPTION: Get a command from the history buffer 182 * 183 ******************************************************************************/ 184 185 char *acpi_db_get_from_history(char *command_num_arg) 186 { 187 u32 cmd_num; 188 189 if (command_num_arg == NULL) { 190 cmd_num = acpi_gbl_next_cmd_num - 1; 191 } 192 193 else { 194 cmd_num = strtoul(command_num_arg, NULL, 0); 195 } 196 197 return (acpi_db_get_history_by_index(cmd_num)); 198 } 199 200 /******************************************************************************* 201 * 202 * FUNCTION: acpi_db_get_history_by_index 203 * 204 * PARAMETERS: cmd_num - Index of the desired history entry. 205 * Values are 0...(acpi_gbl_next_cmd_num - 1) 206 * 207 * RETURN: Pointer to the retrieved command. Null on error. 208 * 209 * DESCRIPTION: Get a command from the history buffer 210 * 211 ******************************************************************************/ 212 213 char *acpi_db_get_history_by_index(u32 cmd_num) 214 { 215 u32 i; 216 u16 history_index; 217 218 /* Search history buffer */ 219 220 history_index = acpi_gbl_lo_history; 221 for (i = 0; i < acpi_gbl_num_history; i++) { 222 if (acpi_gbl_history_buffer[history_index].cmd_num == cmd_num) { 223 224 /* Found the command, return it */ 225 226 return (acpi_gbl_history_buffer[history_index].command); 227 } 228 229 /* History buffer is circular */ 230 231 history_index++; 232 if (history_index >= HISTORY_SIZE) { 233 history_index = 0; 234 } 235 } 236 237 acpi_os_printf("Invalid history number: %u\n", history_index); 238 return (NULL); 239 } 240