From: hhb Date: Sat, 31 Mar 2012 01:58:39 +0000 (+0800) Subject: rk30: fiq serial debugger: add using arrow up and down to search those commands we... X-Git-Tag: firefly_0821_release~9540 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=232e4e6cd19599929e4e741fd1b10e7a723c487d;p=firefly-linux-kernel-4.4.55.git rk30: fiq serial debugger: add using arrow up and down to search those commands we have used, and command auto completes when you press the tab key --- diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c index a0a5a805dfad..d0a8aa8a3216 100644 --- a/arch/arm/common/fiq_debugger.c +++ b/arch/arm/common/fiq_debugger.c @@ -44,6 +44,7 @@ #include "fiq_debugger_ringbuf.h" #define DEBUG_MAX 64 +#define CMD_COUNT 0x0f #define MAX_UNHANDLED_FIQ_COUNT 1000000 #define THREAD_INFO(sp) ((struct thread_info *) \ @@ -68,6 +69,10 @@ struct fiq_debugger_state { char debug_buf[DEBUG_MAX]; int debug_count; + char cmd_buf[CMD_COUNT+1][DEBUG_MAX]; + int back_pointer; + int current_pointer; + bool no_sleep; bool debug_enable; bool ignore_next_wakeup_irq; @@ -543,14 +548,48 @@ static void do_sysrq(struct fiq_debugger_state *state, char rq) /* This function CANNOT be called in FIQ context */ static void debug_irq_exec(struct fiq_debugger_state *state, char *cmd) { + int invalid_cmd = 0; if (!strcmp(cmd, "ps")) do_ps(state); - if (!strcmp(cmd, "sysrq")) + else if (!strcmp(cmd, "sysrq")) do_sysrq(state, 'h'); - if (!strncmp(cmd, "sysrq ", 6)) + else if (!strncmp(cmd, "sysrq ", 6)) do_sysrq(state, cmd[6]); + else { + invalid_cmd = 1; + memset(state->debug_buf, 0, DEBUG_MAX); + } + + if (invalid_cmd == 0) { + state->current_pointer = (state->current_pointer-1) & CMD_COUNT; + if (strcmp(state->cmd_buf[state->current_pointer], state->debug_buf)) { + state->current_pointer = (state->current_pointer+1) & CMD_COUNT; + memset(state->cmd_buf[state->current_pointer], 0, DEBUG_MAX); + strcpy(state->cmd_buf[state->current_pointer], state->debug_buf); + } + memset(state->debug_buf, 0, DEBUG_MAX); + state->current_pointer = (state->current_pointer+1) & CMD_COUNT; + state->back_pointer = state->current_pointer; + } } +static char cmd_buf[][16] = { + {"pc"}, + {"regs"}, + {"allregs"}, + {"bt"}, + {"reboot"}, + {"irqs"}, + {"kmsg"}, + {"version"}, + {"sleep"}, + {"nosleep"}, + {"console"}, + {"cpu"}, + {"ps"}, + {"sysrq"}, +}; + static void debug_help(struct fiq_debugger_state *state) { debug_printf(state, "FIQ Debugger commands:\n" @@ -745,6 +784,109 @@ static int debug_getc(struct fiq_debugger_state *state) return state->pdata->uart_getc(state->pdev); } + +static int debug_cmd_check_back(struct fiq_debugger_state *state, char c) +{ + char *s; + int i = 0; + if (c == 'A') { + state->back_pointer = (state->back_pointer-1) & CMD_COUNT; + if (state->back_pointer != state->current_pointer) { + s = state->cmd_buf[state->back_pointer]; + if (*s != 0) { + for(i = 0; i < strlen(state->debug_buf)-1; i++) { + state->pdata->uart_putc(state->pdev, 8); + state->pdata->uart_putc(state->pdev, ' '); + state->pdata->uart_putc(state->pdev, 8); + } + memset(state->debug_buf, 0, DEBUG_MAX); + strcpy(state->debug_buf, s); + state->debug_count = strlen(state->debug_buf); + debug_printf(state, state->debug_buf); + } else { + state->back_pointer = (state->back_pointer+1) & CMD_COUNT; + } + + } else { + state->back_pointer = (state->back_pointer+1) & CMD_COUNT; + } + } else if (c == 'B') { + + if (state->back_pointer != state->current_pointer) { + state->back_pointer = (state->back_pointer+1) & CMD_COUNT; + if(state->back_pointer == state->current_pointer){ + goto cmd_clear; + } else { + s = state->cmd_buf[state->back_pointer]; + if (*s != 0) { + for(i = 0; i < strlen(state->debug_buf)-1; i++) { + state->pdata->uart_putc(state->pdev, 8); + state->pdata->uart_putc(state->pdev, ' '); + state->pdata->uart_putc(state->pdev, 8); + } + memset(state->debug_buf, 0, DEBUG_MAX); + strcpy(state->debug_buf, s); + state->debug_count = strlen(state->debug_buf); + debug_printf(state, state->debug_buf); + } + } + } else { +cmd_clear: + for(i = 0; i < strlen(state->debug_buf)-1; i++) { + state->pdata->uart_putc(state->pdev, 8); + state->pdata->uart_putc(state->pdev, ' '); + state->pdata->uart_putc(state->pdev, 8); + } + memset(state->debug_buf, 0, DEBUG_MAX); + state->debug_count = 0; + } + } + return 0; +} + +static void debug_cmd_tab(struct fiq_debugger_state *state) +{ + int i,j; + int count = 0; + + for (i = 0; i < ARRAY_SIZE(cmd_buf); i++) { + cmd_buf[i][15] = 1; + } + + for (j = 1; j <= strlen(state->debug_buf); j++) { + count = 0; + for (i = 0; i < ARRAY_SIZE(cmd_buf); i++) { + if (cmd_buf[i][15] == 1) { + if (strncmp(state->debug_buf, cmd_buf[i], j)) { + cmd_buf[i][15] = 0; + } else { + count++; + } + } + } + if (count == 0) + break; + } + + if (count == 1) { + for (i = 0; i < ARRAY_SIZE(cmd_buf); i++) { + if (cmd_buf[i][15] == 1) + break; + } + + for(j = 0; j < strlen(state->debug_buf); j++) { + state->pdata->uart_putc(state->pdev, 8); + state->pdata->uart_putc(state->pdev, ' '); + state->pdata->uart_putc(state->pdev, 8); + } + memset(state->debug_buf, 0, DEBUG_MAX); + strcpy(state->debug_buf, cmd_buf[i]); + state->debug_count = strlen(state->debug_buf); + debug_printf(state, state->debug_buf); + + } +} + static bool debug_handle_uart_interrupt(struct fiq_debugger_state *state, int this_cpu, void *regs, void *svc_sp) { @@ -784,12 +926,26 @@ static bool debug_handle_uart_interrupt(struct fiq_debugger_state *state, state->console_enable = false; debug_puts(state, "fiq debugger mode\n"); state->debug_count = 0; + state->back_pointer = CMD_COUNT; + state->current_pointer = CMD_COUNT; + memset(state->cmd_buf, 0, (CMD_COUNT+1)*DEBUG_MAX); debug_prompt(state); #ifdef CONFIG_FIQ_DEBUGGER_CONSOLE } else if (state->console_enable && state->tty_rbuf) { fiq_debugger_ringbuf_push(state->tty_rbuf, c); signal_helper = true; #endif + } else if (last_c == '[' && (c == 'A' || c == 'B' || c == 'C' || c == 'D')) { + if (state->debug_count > 0) { + state->debug_count--; + state->pdata->uart_putc(state->pdev, 8); + state->pdata->uart_putc(state->pdev, ' '); + state->pdata->uart_putc(state->pdev, 8); + } + debug_cmd_check_back(state, c); + //tab + } else if (c == 9) { + debug_cmd_tab(state); } else if ((c >= ' ') && (c < 127)) { if (state->debug_count < (DEBUG_MAX - 1)) { state->debug_buf[state->debug_count++] = c; @@ -801,6 +957,7 @@ static bool debug_handle_uart_interrupt(struct fiq_debugger_state *state, state->pdata->uart_putc(state->pdev, 8); state->pdata->uart_putc(state->pdev, ' '); state->pdata->uart_putc(state->pdev, 8); + state->debug_buf[state->debug_count] = 0; } } else if ((c == 13) || (c == 10)) { if (c == '\r' || (c == '\n' && last_c != '\r')) { @@ -813,6 +970,17 @@ static bool debug_handle_uart_interrupt(struct fiq_debugger_state *state, signal_helper |= debug_fiq_exec(state, state->debug_buf, regs, svc_sp); + if (signal_helper == false) { + state->current_pointer = (state->current_pointer-1) & CMD_COUNT; + if (strcmp(state->cmd_buf[state->current_pointer], state->debug_buf)) { + state->current_pointer = (state->current_pointer+1) & CMD_COUNT; + memset(state->cmd_buf[state->current_pointer], 0, DEBUG_MAX); + strcpy(state->cmd_buf[state->current_pointer], state->debug_buf); + } + memset(state->debug_buf, 0, DEBUG_MAX); + state->current_pointer = (state->current_pointer+1) & CMD_COUNT; + state->back_pointer = state->current_pointer; + } } else { debug_prompt(state); }