summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-10-26 09:29:40 -0700
committerGerrit <chrome-bot@google.com>2012-10-29 10:36:05 -0700
commitfc6b412589742976db12de4aa64137c03bfbf311 (patch)
treeb32b72aeef1284e9c2d8354d68cc8ef0694712e6 /core
parentbff5a49e6d06c13e67b1a72470dc1d9a2326eb16 (diff)
downloadchrome-ec-fc6b412589742976db12de4aa64137c03bfbf311.tar.gz
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 <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/36695
Diffstat (limited to 'core')
-rw-r--r--core/cortex-m/panic.c114
-rw-r--r--core/cortex-m/task.c5
-rw-r--r--core/cortex-m/timer.c8
-rw-r--r--core/cortex-m/watchdog.c16
4 files changed, 50 insertions, 93 deletions
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 <stdarg.h>
-
-#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 : &regname[(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<<tskid)) {
ccprintf(" Tsk %2d 0x%016lx -> %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();
}