# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1212481970 -3600
# Node ID 5c38568d90df668ce91649bbe2bf2105b27a949b
# Parent fe60bf79d96f285c0f88346ff7ffd0eb2ab19f8e
stubdom: Add console reading support
Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
---
extras/mini-os/console/console.c | 7 +----
extras/mini-os/console/xencons_ring.c | 44 ++++++++++++++++++++++++++++++++++
extras/mini-os/include/console.h | 9 ++++++
extras/mini-os/lib/sys.c | 25 +++++++++++++++++--
4 files changed, 77 insertions(+), 8 deletions(-)
diff -r fe60bf79d96f -r 5c38568d90df 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 Tue Jun 03 09:32:50 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 @@ void xencons_tx(void)
{
/* Do nothing, handled by _rx */
}
+#endif
void console_print(char *data, int length)
diff -r fe60bf79d96f -r 5c38568d90df 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 Tue Jun 03 09:32:50 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 @@ int xencons_ring_send(const char *data,
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 @@ static void handle_input(evtchn_port_t p
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 -r 5c38568d90df 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 Tue Jun 03 09:32:50 2008 +0100
@@ -52,4 +52,13 @@ void init_console(void);
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 -r 5c38568d90df 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 Tue Jun 03 09:32:50 2008 +0100
@@ -213,8 +213,19 @@ int read(int fd, void *buf, size_t nbyte
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 @@ static int select_poll(int nfds, fd_set
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 @@ int select(int nfds, fd_set *readfds, fd
DEFINE_WAIT(w3);
DEFINE_WAIT(w4);
DEFINE_WAIT(w5);
+ DEFINE_WAIT(w6);
assert(thread == main_thread);
@@ -830,6 +847,7 @@ int select(int nfds, fd_set *readfds, fd
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 @@ out:
remove_waiter(w3);
remove_waiter(w4);
remove_waiter(w5);
+ remove_waiter(w6);
return ret;
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|