diff options
author | Randall Spangler <rspangler@chromium.org> | 2012-10-26 09:29:40 -0700 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-10-29 10:36:05 -0700 |
commit | fc6b412589742976db12de4aa64137c03bfbf311 (patch) | |
tree | b32b72aeef1284e9c2d8354d68cc8ef0694712e6 /common/uart_buffering.c | |
parent | bff5a49e6d06c13e67b1a72470dc1d9a2326eb16 (diff) | |
download | chrome-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.c | 79 |
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 */ |