Samuel Thibault
2008-Jun-02 16:56 UTC
[Xen-devel] [PATCH] stubdom: Add console reading support
stubdom: Add console reading support Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com> diff -r fe60bf79d96f extras/mini-os/console/console.c --- a/extras/mini-os/console/console.c Mon Jun 02 16:05:07 2008 +0100 +++ b/extras/mini-os/console/console.c Mon Jun 02 17:30:52 2008 +0100 @@ -49,17 +49,13 @@ of standard dom0 handled console */ #define USE_XEN_CONSOLE -/* Low level functions defined in xencons_ring.c */ -extern int xencons_ring_init(void); -extern int xencons_ring_send(const char *data, unsigned len); -extern int xencons_ring_send_no_notify(const char *data, unsigned len); - /* If console not initialised the printk will be sent to xen serial line NOTE: you need to enable verbose in xen/Rules.mk for it to work. */ static int console_initialised = 0; +#ifndef HAVE_LIBC void xencons_rx(char *buf, unsigned len, struct pt_regs *regs) { if(len > 0) @@ -77,6 +73,7 @@ { /* Do nothing, handled by _rx */ } +#endif void console_print(char *data, int length) diff -r fe60bf79d96f extras/mini-os/console/xencons_ring.c --- a/extras/mini-os/console/xencons_ring.c Mon Jun 02 16:05:07 2008 +0100 +++ b/extras/mini-os/console/xencons_ring.c Mon Jun 02 17:45:02 2008 +0100 @@ -8,6 +8,7 @@ #include <xenbus.h> #include <xen/io/console.h> +DECLARE_WAIT_QUEUE_HEAD(console_queue); static inline struct xencons_interface *xencons_interface(void) { @@ -52,6 +53,9 @@ static void handle_input(evtchn_port_t port, struct pt_regs *regs, void *ign) { +#ifdef HAVE_LIBC + wake_up(&console_queue); +#else struct xencons_interface *intf = xencons_interface(); XENCONS_RING_IDX cons, prod; @@ -71,7 +75,47 @@ notify_daemon(); xencons_tx(); +#endif } + +#ifdef HAVE_LIBC +int xencons_ring_avail(void) +{ + struct xencons_interface *intf = xencons_interface(); + XENCONS_RING_IDX cons, prod; + + cons = intf->in_cons; + prod = intf->in_prod; + mb(); + BUG_ON((prod - cons) > sizeof(intf->in)); + + return prod - cons; +} + +int xencons_ring_recv(char *data, unsigned len) +{ + struct xencons_interface *intf = xencons_interface(); + XENCONS_RING_IDX cons, prod; + unsigned filled = 0; + + cons = intf->in_cons; + prod = intf->in_prod; + mb(); + BUG_ON((prod - cons) > sizeof(intf->in)); + + while (filled < len && cons + filled != prod) { + data[filled] = *(intf->in + MASK_XENCONS_IDX(cons + filled, intf->in)); + filled++; + } + + mb(); + intf->in_cons = cons + filled; + + notify_daemon(); + + return filled; +} +#endif int xencons_ring_init(void) { diff -r fe60bf79d96f extras/mini-os/include/console.h --- a/extras/mini-os/include/console.h Mon Jun 02 16:05:07 2008 +0100 +++ b/extras/mini-os/include/console.h Mon Jun 02 17:45:02 2008 +0100 @@ -51,5 +51,14 @@ void init_console(void); void console_print(char *data, int length); + +/* Low level functions defined in xencons_ring.c */ +extern struct wait_queue_head console_queue; +int xencons_ring_init(void); +int xencons_ring_send(const char *data, unsigned len); +int xencons_ring_send_no_notify(const char *data, unsigned len); +int xencons_ring_avail(void); +int xencons_ring_recv(char *data, unsigned len); + #endif /* _LIB_CONSOLE_H_ */ diff -r fe60bf79d96f extras/mini-os/lib/sys.c --- a/extras/mini-os/lib/sys.c Mon Jun 02 16:05:07 2008 +0100 +++ b/extras/mini-os/lib/sys.c Mon Jun 02 17:45:02 2008 +0100 @@ -213,8 +213,19 @@ int read(int fd, void *buf, size_t nbytes) { switch (files[fd].type) { - case FTYPE_CONSOLE: - return 0; + case FTYPE_CONSOLE: { + int ret; + DEFINE_WAIT(w); + while(1) { + add_waiter(w, console_queue); + ret = xencons_ring_recv(buf, nbytes); + if (ret) + break; + schedule(); + } + remove_waiter(w); + return ret; + } case FTYPE_FILE: { ssize_t ret; if (nbytes > PAGE_SIZE) @@ -707,7 +718,12 @@ FD_CLR(i, exceptfds); break; case FTYPE_CONSOLE: - FD_CLR(i, readfds); + if (FD_ISSET(i, writefds)) { + if (xencons_ring_avail()) + n++; + else + FD_CLR(i, readfds); + } if (FD_ISSET(i, writefds)) n++; FD_CLR(i, exceptfds); @@ -809,6 +825,7 @@ DEFINE_WAIT(w3); DEFINE_WAIT(w4); DEFINE_WAIT(w5); + DEFINE_WAIT(w6); assert(thread == main_thread); @@ -830,6 +847,7 @@ add_waiter(w3, blkfront_queue); add_waiter(w4, xenbus_watch_queue); add_waiter(w5, kbdfront_queue); + add_waiter(w6, console_queue); if (readfds) myread = *readfds; @@ -916,6 +934,7 @@ remove_waiter(w3); remove_waiter(w4); remove_waiter(w5); + remove_waiter(w6); return ret; } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel