Hi Simon, Le 15/10/2011 02:03, Simon Glass a écrit : > From: Scott Wood<scottw...@freescale.com> > > From: Scott Wood<scottw...@freescale.com> > > This improves the performance of U-Boot when accepting rapid input, > such as pasting a sequence of commands. > > Without this patch, on P4080DS I see a maximum of around 5 lines can > be pasted. With this patch, it handles around 70 lines before lossage, > long enough for most things you'd paste. > > With it enabled, on ppc it's an extra 396 bytes of image size, and 1056 > bytes of BSS. > > ARM note from Simon Glass<s...@chromium.org> - ARM code size goes from > 212 to 484 bytes (extra 272 bytes), BSS to 1056 bytes. > > Signed-off-by: Scott Wood<scottw...@freescale.com> > --- > Changes in v2: > - Fix checkpatch warnings, the other one was already there
A general question: is the issue with input as such, or with echoing this input? > README | 8 ++++ > drivers/serial/ns16550.c | 96 > +++++++++++++++++++++++++++++++++++++++++++-- > drivers/serial/serial.c | 5 +- > include/ns16550.h | 4 +- > 4 files changed, 104 insertions(+), 9 deletions(-) > > diff --git a/README b/README > index 7e032a9..28d2e8a 100644 > --- a/README > +++ b/README > @@ -2862,6 +2862,14 @@ use the "saveenv" command to store a valid environment. > space for already greatly restricted images, including but not > limited to NAND_SPL configurations. > > +- CONFIG_NS16550_BUFFER_READS: > + Instead of reading directly from the receive register > + every time U-Boot is ready for another byte, keep a > + buffer and fill it from the hardware fifo every time > + U-Boot reads a character. This helps U-Boot keep up with > + a larger amount of rapid input, such as happens when > + pasting text into the terminal. > + > Low Level (hardware related) configuration options: > --------------------------------------------------- > > diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c > index 0174744..a012e5d 100644 > --- a/drivers/serial/ns16550.c > +++ b/drivers/serial/ns16550.c > @@ -4,12 +4,15 @@ > * modified to use CONFIG_SYS_ISA_MEM and new defines > */ > > +#include<common.h> > #include<config.h> > #include<ns16550.h> > #include<watchdog.h> > #include<linux/types.h> > #include<asm/io.h> > > +DECLARE_GLOBAL_DATA_PTR; > + > #define UART_LCRVAL UART_LCR_8N1 /* 8 data, 1 stop, no parity */ > #define UART_MCRVAL (UART_MCR_DTR | \ > UART_MCR_RTS) /* RTS/DTR */ > @@ -92,21 +95,104 @@ void NS16550_putc (NS16550_t com_port, char c) > } > > #ifndef CONFIG_NS16550_MIN_FUNCTIONS > -char NS16550_getc (NS16550_t com_port) > + > +static char NS16550_raw_getc(NS16550_t regs) > { > - while ((serial_in(&com_port->lsr)& UART_LSR_DR) == 0) { > + while ((serial_in(®s->lsr)& UART_LSR_DR) == 0) { > #ifdef CONFIG_USB_TTY > extern void usbtty_poll(void); > usbtty_poll(); > #endif > WATCHDOG_RESET(); > } > - return serial_in(&com_port->rbr); > + return serial_in(®s->rbr); > +} > + > +static int NS16550_raw_tstc(NS16550_t regs) > +{ > + return ((serial_in(®s->lsr)& UART_LSR_DR) != 0); > +} > + > + > +#ifdef CONFIG_NS16550_BUFFER_READS > + > +#define BUF_SIZE 256 I guess this define conditions how well U-Boot will cope with steady high-rate input, correct? If so, I'd like it to be a configuration option -- actually, one could combine enabling the option *and* setting the expected buffer size. > +#define NUM_PORTS 4 > + > +struct ns16550_priv { > + char buf[BUF_SIZE]; > + unsigned int head, tail; > +}; > + > +static struct ns16550_priv rxstate[NUM_PORTS]; > + > +static void enqueue(unsigned int port, char ch) > +{ > + /* If queue is full, drop the character. */ > + if ((rxstate[port].head - rxstate[port].tail - 1) % BUF_SIZE == 0) > + return; > + > + rxstate[port].buf[rxstate[port].tail] = ch; > + rxstate[port].tail = (rxstate[port].tail + 1) % BUF_SIZE; > +} > + > +static int dequeue(unsigned int port, char *ch) > +{ > + /* Empty queue? */ > + if (rxstate[port].head == rxstate[port].tail) > + return 0; > + > + *ch = rxstate[port].buf[rxstate[port].head]; > + rxstate[port].head = (rxstate[port].head + 1) % BUF_SIZE; > + return 1; > +} > + > +static void fill_rx_buf(NS16550_t regs, unsigned int port) > +{ > + while ((serial_in(®s->lsr)& UART_LSR_DR) != 0) > + enqueue(port, serial_in(®s->rbr)); > +} > + > +char NS16550_getc(NS16550_t regs, unsigned int port) > +{ > + char ch; > + > + if (port>= NUM_PORTS || !(gd->flags& GD_FLG_RELOC)) > + return NS16550_raw_getc(regs); > + > + do { > +#ifdef CONFIG_USB_TTY > + extern void usbtty_poll(void); > + usbtty_poll(); > +#endif > + fill_rx_buf(regs, port); > + WATCHDOG_RESET(); > + } while (!dequeue(port,&ch)); > + > + return ch; > +} > + > +int NS16550_tstc(NS16550_t regs, unsigned int port) > +{ > + if (port>= NUM_PORTS || !(gd->flags& GD_FLG_RELOC)) > + return NS16550_raw_tstc(regs); > + > + fill_rx_buf(regs, port); > + > + return rxstate[port].head != rxstate[port].tail; > +} > + > +#else /* CONFIG_NS16550_BUFFER_READS */ > + > +char NS16550_getc(NS16550_t regs, unsigned int port) > +{ > + return NS16550_raw_getc(regs); > } > > -int NS16550_tstc (NS16550_t com_port) > +int NS16550_tstc(NS16550_t regs, unsigned int port) > { > - return ((serial_in(&com_port->lsr)& UART_LSR_DR) != 0); > + return NS16550_raw_tstc(regs); > } > > +#endif /* CONFIG_NS16550_BUFFER_READS */ > #endif /* CONFIG_NS16550_MIN_FUNCTIONS */ > diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c > index 0d56e78..cf9a1dd 100644 > --- a/drivers/serial/serial.c > +++ b/drivers/serial/serial.c > @@ -93,6 +93,7 @@ static NS16550_t serial_ports[4] = { > }; > > #define PORT serial_ports[port-1] > +#define PORTNR (port-1) > #if defined(CONFIG_CONS_INDEX) > #define CONSOLE (serial_ports[CONFIG_CONS_INDEX-1]) > #endif > @@ -219,13 +220,13 @@ _serial_puts (const char *s,const int port) > int > _serial_getc(const int port) > { > - return NS16550_getc(PORT); > + return NS16550_getc(PORT, PORTNR); > } > > int > _serial_tstc(const int port) > { > - return NS16550_tstc(PORT); > + return NS16550_tstc(PORT, PORTNR); > } > > void > diff --git a/include/ns16550.h b/include/ns16550.h > index 51f1c17..60b0abc 100644 > --- a/include/ns16550.h > +++ b/include/ns16550.h > @@ -164,6 +164,6 @@ typedef volatile struct NS16550 *NS16550_t; > > void NS16550_init (NS16550_t com_port, int baud_divisor); > void NS16550_putc (NS16550_t com_port, char c); > -char NS16550_getc (NS16550_t com_port); > -int NS16550_tstc (NS16550_t com_port); > +char NS16550_getc(NS16550_t regs, unsigned int port); > +int NS16550_tstc(NS16550_t regs, unsigned int port); > void NS16550_reinit (NS16550_t com_port, int baud_divisor); Amicalement, -- Albert. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot