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