summaryrefslogtreecommitdiff
path: root/common/uart_buffering.c
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 /common/uart_buffering.c
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 'common/uart_buffering.c')
-rw-r--r--common/uart_buffering.c79
1 files changed, 29 insertions, 50 deletions
diff --git a/common/uart_buffering.c b/common/uart_buffering.c
index 6f22576762..5251507b38 100644
--- a/common/uart_buffering.c
+++ b/common/uart_buffering.c
@@ -479,6 +479,19 @@ static void handle_console_char(int c)
}
/**
+ * Copy output from buffer until TX fifo full or output buffer empty.
+ *
+ * May be called from interrupt context.
+ */
+static void fill_tx_fifo(void)
+{
+ while (uart_tx_ready() && (tx_buf_head != tx_buf_tail)) {
+ uart_write_char(tx_buf[tx_buf_tail]);
+ tx_buf_tail = TX_BUF_NEXT(tx_buf_tail);
+ }
+}
+
+/**
* Helper for UART processing.
*/
void uart_process(void)
@@ -488,10 +501,7 @@ void uart_process(void)
handle_console_char(uart_read_char());
/* Copy output from buffer until TX fifo full or output buffer empty */
- while (uart_tx_ready() && (tx_buf_head != tx_buf_tail)) {
- uart_write_char(tx_buf[tx_buf_tail]);
- tx_buf_tail = TX_BUF_NEXT(tx_buf_tail);
- }
+ fill_tx_fifo();
/* If output buffer is empty, disable transmit interrupt */
if (tx_buf_tail == tx_buf_head)
@@ -534,37 +544,23 @@ int uart_printf(const char *format, ...)
return rv;
}
-/**
- * Add a character directly to the UART buffer.
- */
-static int emergency_txchar(void *format, int c)
-{
- /* Wait for space */
- while (!uart_tx_ready())
- ;
-
- /* Write the character */
- uart_write_char(c);
- return 0;
-}
-
-int uart_emergency_printf(const char *format, ...)
-{
- int rv;
- va_list args;
-
- va_start(args, format);
- rv = vfnprintf(emergency_txchar, NULL, format, args);
- va_end(args);
-
- /* Wait for transmit FIFO empty */
- uart_tx_flush();
-
- return rv;
-}
-
void uart_flush_output(void)
{
+ /*
+ * If we're in interrupt context, copy output explicitly, since the
+ * UART interrupt may not be able to preempt this one.
+ */
+ if (in_interrupt_context()) {
+ do {
+ /* Copy until TX fifo full or output buffer empty */
+ fill_tx_fifo();
+
+ /* Wait for transmit FIFO empty */
+ uart_tx_flush();
+ } while (tx_buf_head != tx_buf_tail);
+ return;
+ }
+
/* Wait for buffer to empty */
while (tx_buf_head != tx_buf_tail) {
/*
@@ -584,23 +580,6 @@ void uart_flush_output(void)
uart_tx_flush();
}
-void uart_emergency_flush(void)
-{
- do {
- /*
- * Copy output from buffer until TX fifo full or output buffer
- * empty.
- */
- while (uart_tx_ready() &&
- (tx_buf_head != tx_buf_tail)) {
- uart_write_char(tx_buf[tx_buf_tail]);
- tx_buf_tail = TX_BUF_NEXT(tx_buf_tail);
- }
- /* Wait for transmit FIFO empty */
- uart_tx_flush();
- } while (tx_buf_head != tx_buf_tail);
-}
-
void uart_flush_input(void)
{
/* Disable interrupts */