1 Commits

Author SHA1 Message Date
Travis Geiselbrecht
467c5bf191 [lib][console] add a global input queue that anyone can push into
Changes the console from a pull to a push model from platform into the
queue, which may break the model of some of the drivers. At the moment
make it optional.
2016-02-15 14:05:10 -08:00
6 changed files with 56 additions and 9 deletions

View File

@@ -28,10 +28,12 @@
#include <assert.h>
#include <list.h>
#include <string.h>
#include <lib/cbuf.h>
#include <arch/ops.h>
#include <platform.h>
#include <platform/debug.h>
#include <kernel/thread.h>
#include <lk/init.h>
/* routines for dealing with main console io */
@@ -44,6 +46,16 @@
static spin_lock_t print_spin_lock = 0;
static struct list_node print_callbacks = LIST_INITIAL_VALUE(print_callbacks);
#if CONSOLE_HAS_INPUT_BUFFER
#ifndef CONSOLE_BUF_LEN
#define CONSOLE_BUF_LEN 256
#endif
/* global input circular buffer */
cbuf_t console_input_cbuf;
static uint8_t console_cbuf_buf[CONSOLE_BUF_LEN];
#endif // CONSOLE_HAS_INPUT_BUFFER
/* print lock must be held when invoking out, outs, outc */
static void out_count(const char *str, size_t len)
{
@@ -100,13 +112,27 @@ static ssize_t __debug_stdio_read(io_handle_t *io, char *s, size_t len)
if (len == 0)
return 0;
#if CONSOLE_HAS_INPUT_BUFFER
ssize_t err = cbuf_read(&console_input_cbuf, s, len, true);
return err;
#else
int err = platform_dgetc(s, true);
if (err < 0)
return err;
return 1;
#endif
}
#if CONSOLE_HAS_INPUT_BUFFER
void console_init_hook(uint level)
{
cbuf_initialize_etc(&console_input_cbuf, sizeof(console_cbuf_buf), console_cbuf_buf);
}
LK_INIT_HOOK(console, console_init_hook, LK_INIT_LEVEL_PLATFORM_EARLY - 1);
#endif
/* global console io handle */
static const io_handle_hooks_t console_io_hooks = {
.write = __debug_stdio_write,
@@ -114,3 +140,4 @@ static const io_handle_hooks_t console_io_hooks = {
};
io_handle_t console_io = IO_HANDLE_INITIAL_VALUE(&console_io_hooks);

View File

@@ -69,5 +69,14 @@ static inline void io_handle_init(io_handle_t *io, io_handle_hooks_t *hooks)
/* the main console io handle */
extern io_handle_t console_io;
#ifndef CONSOLE_HAS_INPUT_BUFFER
#define CONSOLE_HAS_INPUT_BUFFER 0
#endif
#if CONSOLE_HAS_INPUT_BUFFER
/* main input circular buffer that acts as the default input queue */
typedef struct cbuf cbuf_t;
extern cbuf_t console_input_cbuf;
#endif
__END_CDECLS

View File

@@ -3,6 +3,7 @@ LOCAL_DIR := $(GET_LOCAL_DIR)
MODULE := $(LOCAL_DIR)
MODULE_DEPS := \
lib/cbuf
MODULE_SRCS += \
$(LOCAL_DIR)/console.c \

View File

@@ -36,5 +36,5 @@ __WEAK void platform_pputc(char c)
__WEAK int platform_pgetc(char *c, bool wait)
{
return platform_dgetc(c, wait);
return 0;
}

View File

@@ -37,7 +37,8 @@ MODULE_DEPS += \
GLOBAL_DEFINES += \
MEMBASE=$(MEMBASE) \
MEMSIZE=$(MEMSIZE) \
PLATFORM_SUPPORTS_PANIC_SHELL=1
PLATFORM_SUPPORTS_PANIC_SHELL=1 \
CONSOLE_HAS_INPUT_BUFFER=1
GLOBAL_DEFINES += MMU_WITH_TRAMPOLINE=1 \

View File

@@ -28,6 +28,7 @@
#include <platform/interrupts.h>
#include <platform/debug.h>
#include <platform/qemu-virt.h>
#include <target/debugconfig.h>
/* PL011 implementation */
#define UART_DR (0x00)
@@ -75,14 +76,22 @@ static enum handler_return uart_irq(void *arg)
/* while fifo is not empty, read chars out of it */
while ((UARTREG(base, UART_TFR) & (1<<4)) == 0) {
/* if we're out of rx buffer, mask the irq instead of handling it */
if (cbuf_space_avail(rxbuf) == 0) {
UARTREG(base, UART_IMSC) &= ~(1<<4); // !rxim
break;
}
#if CONSOLE_HAS_INPUT_BUFFER
if (port == DEBUG_UART) {
char c = UARTREG(base, UART_DR);
cbuf_write_char(&console_input_cbuf, c, false);
} else
#endif
{
/* if we're out of rx buffer, mask the irq instead of handling it */
if (cbuf_space_avail(rxbuf) == 0) {
UARTREG(base, UART_IMSC) &= ~(1<<4); // !rxim
break;
}
char c = UARTREG(base, UART_DR);
cbuf_write_char(rxbuf, c, false);
char c = UARTREG(base, UART_DR);
cbuf_write_char(rxbuf, c, false);
}
resched = true;
}