From fc6b412589742976db12de4aa64137c03bfbf311 Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Fri, 26 Oct 2012 09:29:40 -0700 Subject: Consolidate emergency debug output This removes the duplicate uart_emergency_printf() vs. panic_printf() / uart_emergency_puts() vs. panic_puts() implementation and saves ~0.5kb of code size. The other significant change is that uart_flush_output() is now smart enough to determine if it's in an interrupt; if so, it will spin-flush the output buffer instead of waiting on the uart interrupt. This removes the need for a separate panic_flush(). BUG=chrome-os-partner:15579 BRANCH=none TEST=crash unaligned; should print well-formatted crash dump Change-Id: Ifae756203dd1881806be563308077c1d68302e1f Signed-off-by: Randall Spangler Reviewed-on: https://gerrit.chromium.org/gerrit/36695 --- core/cortex-m/panic.c | 114 +++++++++++++++++------------------------------ core/cortex-m/task.c | 5 +-- core/cortex-m/timer.c | 8 ++-- core/cortex-m/watchdog.c | 16 +++---- 4 files changed, 50 insertions(+), 93 deletions(-) (limited to 'core') diff --git a/core/cortex-m/panic.c b/core/cortex-m/panic.c index 5b0bff89e7..91ea733f04 100644 --- a/core/cortex-m/panic.c +++ b/core/cortex-m/panic.c @@ -3,13 +3,12 @@ * found in the LICENSE file. */ -#include - -#include "config.h" +#include "common.h" #include "console.h" #include "cpu.h" #include "host_command.h" #include "panic.h" +#include "printf.h" #include "system.h" #include "task.h" #include "timer.h" @@ -33,83 +32,54 @@ static struct panic_data * const pdata_ptr = static const uint32_t pstack_addr = (CONFIG_RAM_BASE + CONFIG_RAM_SIZE - sizeof(struct panic_data)) & ~7; -void panic_putc(int ch) -{ - uart_emergency_flush(); - if (ch == '\n') - panic_putc('\r'); - uart_write_char(ch); - uart_tx_flush(); -} - -void panic_puts(const char *s) -{ - while (*s) - panic_putc(*s++); -} - -void panic_vprintf(const char *format, va_list args) +/** + * Add a character directly to the UART buffer. + * + * @param context Context; ignored. + * @param c Character to write. + * @return 0 if the character was transmitted, 1 if it was dropped. + */ +static int panic_txchar(void *context, int c) { - int pad_width; + if (c == '\n') + panic_txchar(context, '\r'); - while (*format) { - int c = *format++; + /* Wait for space in transmit FIFO */ + while (!uart_tx_ready()) + ; - /* Copy normal characters */ - if (c != '%') { - panic_putc(c); - continue; - } + /* Write the character directly to the transmit FIFO */ + uart_write_char(c); - /* Get first format character */ - c = *format++; + return 0; +} - /* Handle %c */ - if (c == 'c') { - c = va_arg(args, int); - panic_putc(c); - continue; - } +void panic_puts(const char *outstr) +{ + /* Flush the output buffer */ + uart_flush_output(); - /* Count padding length (only supported for hex) */ - pad_width = 0; - while (c >= '0' && c <= '9') { - pad_width = (10 * pad_width) + c - '0'; - c = *format++; - } + /* Put all characters in the output buffer */ + while (*outstr) + panic_txchar(NULL, *outstr++); - if (c == 's') { - char *vstr; - - vstr = va_arg(args, char *); - panic_puts(vstr ? vstr : "(null)"); - } else { /* assume 'x' */ - uint32_t v, shift; - int i; - - v = va_arg(args, uint32_t); - if (!pad_width) - pad_width = 8; - shift = pad_width * 4 - 4; - for (i = 0; i < pad_width; i++) { - int ch = '0' + ((v >> shift) & 0xf); - - if (ch > '9') - ch += 'a' - '9' - 1; - panic_putc(ch); - shift -= 4; - } - } - } + /* Flush the transmit FIFO */ + uart_tx_flush(); } void panic_printf(const char *format, ...) { va_list args; + /* Flush the output buffer */ + uart_flush_output(); + va_start(args, format); - panic_vprintf(format, args); + vfnprintf(panic_txchar, NULL, format, args); va_end(args); + + /* Flush the transmit FIFO */ + uart_tx_flush(); } /** @@ -143,10 +113,10 @@ static void print_reg(int regnum, const uint32_t *regs, int index) name = regnum < 10 ? rname : ®name[(regnum - 10) * 3]; panic_printf("%c%c%c:", name[0], name[1], name[2]); if (regs) - panic_printf("%8x", regs[index]); + panic_printf("%08x", regs[index]); else panic_puts(" "); - panic_putc((regnum & 3) == 3 ? '\n' : ' '); + panic_puts((regnum & 3) == 3 ? "\n" : " "); } #ifdef CONFIG_PANIC_HELP @@ -269,15 +239,13 @@ static void panic_show_extra(const struct panic_data *pdata) panic_printf(", bfar = %x", pdata->bfar); if (pdata->mmfs & CPU_NVIC_MMFS_MFARVALID) panic_printf(", mfar = %x", pdata->mfar); - panic_putc('\n'); - panic_printf("mmfs = %x, ", pdata->mmfs); + panic_printf("\nmmfs = %x, ", pdata->mmfs); panic_printf("shcsr = %x, ", pdata->shcsr); panic_printf("hfsr = %x, ", pdata->hfsr); panic_printf("dfsr = %x\n", pdata->dfsr); } #endif /* CONFIG_PANIC_HELP */ - /** * Display a message and reboot */ @@ -299,7 +267,7 @@ static void panic_print(const struct panic_data *pdata) if (pdata->flags & PANIC_DATA_FLAG_FRAME_VALID) sregs = pdata->frame; - panic_printf("\n=== EXCEPTION: %2x ====== xPSR: %8x ===========\n", + panic_printf("\n=== EXCEPTION: %02x ====== xPSR: %08x ===========\n", lregs[1] & 7, sregs ? sregs[7] : -1); for (i = 0; i < 4; i++) print_reg(i, sregs, i); @@ -415,8 +383,8 @@ void ignore_bus_fault(int ignored) void panic_assert_fail(const char *msg, const char *func, const char *fname, int linenum) { - panic_printf("\nASSERTION FAILURE '%s' in %s() at %s:%d\n", msg, func, - fname, linenum); + panic_printf("\nASSERTION FAILURE '%s' in %s() at %s:%d\n", + msg, func, fname, linenum); panic_reboot(); } diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c index 7b4eb9ddfe..c48a5e3068 100644 --- a/core/cortex-m/task.c +++ b/core/cortex-m/task.c @@ -497,10 +497,7 @@ void task_print_list(void) ccprintf("%4d %c %-16s %08x %11.6ld %3d/%3d\n", i, is_ready, task_names[i], tasks[i].events, tasks[i].runtime, stackused, tasks_init[i].stack_size); - if (in_interrupt_context()) - uart_emergency_flush(); - else - cflush(); + cflush(); } } diff --git a/core/cortex-m/timer.c b/core/cortex-m/timer.c index d3eaae7efb..5038706a24 100644 --- a/core/cortex-m/timer.c +++ b/core/cortex-m/timer.c @@ -188,20 +188,18 @@ void timer_print_info(void) "Deadline: 0x%016lx -> %11.6ld s from now\n" "Active timers:\n", t, deadline, deadline - t); + cflush(); + for (tskid = 0; tskid < TASK_ID_COUNT; tskid++) { if (timer_running & (1< %11.6ld\n", tskid, timer_deadline[tskid].val, timer_deadline[tskid].val - t); - if (in_interrupt_context()) - uart_emergency_flush(); - else - cflush(); + cflush(); } } } - static int command_wait(int argc, char **argv) { char *e; diff --git a/core/cortex-m/watchdog.c b/core/cortex-m/watchdog.c index d21bb4f1ec..ae26734692 100644 --- a/core/cortex-m/watchdog.c +++ b/core/cortex-m/watchdog.c @@ -5,16 +5,14 @@ /* Watchdog common code */ -#include "board.h" #include "common.h" -#include "config.h" +#include "panic.h" #include "registers.h" #include "task.h" #include "timer.h" #include "uart.h" #include "watchdog.h" - void watchdog_trace(uint32_t excep_lr, uint32_t excep_sp) { uint32_t psp; @@ -29,21 +27,17 @@ void watchdog_trace(uint32_t excep_lr, uint32_t excep_sp) stack = (uint32_t *)psp; } - uart_printf("### WATCHDOG PC=%08x / LR=%08x / pSP=%08x ", - stack[6], stack[5], psp); + panic_printf("### WATCHDOG PC=%08x / LR=%08x / pSP=%08x ", + stack[6], stack[5], psp); if ((excep_lr & 0xf) == 1) - uart_puts("(exc) ###\n"); + panic_puts("(exc) ###\n"); else - uart_printf("(task %d) ###\n", task_get_current()); - /* Ensure this debug message is always flushed to the UART */ - uart_emergency_flush(); + panic_printf("(task %d) ###\n", task_get_current()); /* If we are blocked in a high priority IT handler, the following debug * messages might not appear but they are useless in that situation. */ timer_print_info(); - uart_emergency_flush(); task_print_list(); - uart_emergency_flush(); } -- cgit v1.2.1