1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /****************************************************************************** 3 * 4 * Module Name: dbhistry - debugger HISTORY command 5 * 6 * Copyright (C) 2000 - 2019, Intel Corp. 7 * 8 *****************************************************************************/ 9 10 #include <acpi/acpi.h> 11 #include "accommon.h" 12 #include "acdebug.h" 13 14 #define _COMPONENT ACPI_CA_DEBUGGER 15 ACPI_MODULE_NAME("dbhistry") 16 17 #define HI_NO_HISTORY 0 18 #define HI_RECORD_HISTORY 1 19 #define HISTORY_SIZE 40 20 typedef struct history_info { 21 char *command; 22 u32 cmd_num; 23 24 } HISTORY_INFO; 25 26 static HISTORY_INFO acpi_gbl_history_buffer[HISTORY_SIZE]; 27 static u16 acpi_gbl_lo_history = 0; 28 static u16 acpi_gbl_num_history = 0; 29 static u16 acpi_gbl_next_history_index = 0; 30 u32 acpi_gbl_next_cmd_num = 1; 31 32 /******************************************************************************* 33 * 34 * FUNCTION: acpi_db_add_to_history 35 * 36 * PARAMETERS: command_line - Command to add 37 * 38 * RETURN: None 39 * 40 * DESCRIPTION: Add a command line to the history buffer. 41 * 42 ******************************************************************************/ 43 44 void acpi_db_add_to_history(char *command_line) 45 { 46 u16 cmd_len; 47 u16 buffer_len; 48 49 /* Put command into the next available slot */ 50 51 cmd_len = (u16)strlen(command_line); 52 if (!cmd_len) { 53 return; 54 } 55 56 if (acpi_gbl_history_buffer[acpi_gbl_next_history_index].command != 57 NULL) { 58 buffer_len = 59 (u16) 60 strlen(acpi_gbl_history_buffer[acpi_gbl_next_history_index]. 61 command); 62 63 if (cmd_len > buffer_len) { 64 acpi_os_free(acpi_gbl_history_buffer 65 [acpi_gbl_next_history_index].command); 66 acpi_gbl_history_buffer[acpi_gbl_next_history_index]. 67 command = acpi_os_allocate(cmd_len + 1); 68 } 69 } else { 70 acpi_gbl_history_buffer[acpi_gbl_next_history_index].command = 71 acpi_os_allocate(cmd_len + 1); 72 } 73 74 strcpy(acpi_gbl_history_buffer[acpi_gbl_next_history_index].command, 75 command_line); 76 77 acpi_gbl_history_buffer[acpi_gbl_next_history_index].cmd_num = 78 acpi_gbl_next_cmd_num; 79 80 /* Adjust indexes */ 81 82 if ((acpi_gbl_num_history == HISTORY_SIZE) && 83 (acpi_gbl_next_history_index == acpi_gbl_lo_history)) { 84 acpi_gbl_lo_history++; 85 if (acpi_gbl_lo_history >= HISTORY_SIZE) { 86 acpi_gbl_lo_history = 0; 87 } 88 } 89 90 acpi_gbl_next_history_index++; 91 if (acpi_gbl_next_history_index >= HISTORY_SIZE) { 92 acpi_gbl_next_history_index = 0; 93 } 94 95 acpi_gbl_next_cmd_num++; 96 if (acpi_gbl_num_history < HISTORY_SIZE) { 97 acpi_gbl_num_history++; 98 } 99 } 100 101 /******************************************************************************* 102 * 103 * FUNCTION: acpi_db_display_history 104 * 105 * PARAMETERS: None 106 * 107 * RETURN: None 108 * 109 * DESCRIPTION: Display the contents of the history buffer 110 * 111 ******************************************************************************/ 112 113 void acpi_db_display_history(void) 114 { 115 u32 i; 116 u16 history_index; 117 118 history_index = acpi_gbl_lo_history; 119 120 /* Dump entire history buffer */ 121 122 for (i = 0; i < acpi_gbl_num_history; i++) { 123 if (acpi_gbl_history_buffer[history_index].command) { 124 acpi_os_printf("%3ld %s\n", 125 acpi_gbl_history_buffer[history_index]. 126 cmd_num, 127 acpi_gbl_history_buffer[history_index]. 128 command); 129 } 130 131 history_index++; 132 if (history_index >= HISTORY_SIZE) { 133 history_index = 0; 134 } 135 } 136 } 137 138 /******************************************************************************* 139 * 140 * FUNCTION: acpi_db_get_from_history 141 * 142 * PARAMETERS: command_num_arg - String containing the number of the 143 * command to be retrieved 144 * 145 * RETURN: Pointer to the retrieved command. Null on error. 146 * 147 * DESCRIPTION: Get a command from the history buffer 148 * 149 ******************************************************************************/ 150 151 char *acpi_db_get_from_history(char *command_num_arg) 152 { 153 u32 cmd_num; 154 155 if (command_num_arg == NULL) { 156 cmd_num = acpi_gbl_next_cmd_num - 1; 157 } 158 159 else { 160 cmd_num = strtoul(command_num_arg, NULL, 0); 161 } 162 163 return (acpi_db_get_history_by_index(cmd_num)); 164 } 165 166 /******************************************************************************* 167 * 168 * FUNCTION: acpi_db_get_history_by_index 169 * 170 * PARAMETERS: cmd_num - Index of the desired history entry. 171 * Values are 0...(acpi_gbl_next_cmd_num - 1) 172 * 173 * RETURN: Pointer to the retrieved command. Null on error. 174 * 175 * DESCRIPTION: Get a command from the history buffer 176 * 177 ******************************************************************************/ 178 179 char *acpi_db_get_history_by_index(u32 cmd_num) 180 { 181 u32 i; 182 u16 history_index; 183 184 /* Search history buffer */ 185 186 history_index = acpi_gbl_lo_history; 187 for (i = 0; i < acpi_gbl_num_history; i++) { 188 if (acpi_gbl_history_buffer[history_index].cmd_num == cmd_num) { 189 190 /* Found the command, return it */ 191 192 return (acpi_gbl_history_buffer[history_index].command); 193 } 194 195 /* History buffer is circular */ 196 197 history_index++; 198 if (history_index >= HISTORY_SIZE) { 199 history_index = 0; 200 } 201 } 202 203 acpi_os_printf("Invalid history number: %u\n", history_index); 204 return (NULL); 205 } 206