# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 43474e663b3d34ad2ad7de728ff25f96200aab3b
# Parent 09378a9ca8ad33fbae906100f728f81bb57dcc71
[MINIOS]Events handling cleaned up. The interface extended to provide
void* pointer to handlers.
Signed-off-by: Steven Smith <sos22@xxxxxxxxx>
Signed-off-by: Grzegorz Milos <gm281@xxxxxxxxx>
---
extras/mini-os/console/xencons_ring.c | 5 +-
extras/mini-os/events.c | 84 +++++++++++++++++++++-------------
extras/mini-os/include/events.h | 24 ++-------
extras/mini-os/include/lib.h | 13 +++++
extras/mini-os/lib/string.c | 10 ++++
extras/mini-os/time.c | 6 +-
extras/mini-os/xenbus/xenbus.c | 5 +-
7 files changed, 93 insertions(+), 54 deletions(-)
diff -r 09378a9ca8ad -r 43474e663b3d extras/mini-os/console/xencons_ring.c
--- a/extras/mini-os/console/xencons_ring.c Wed Jul 05 11:27:25 2006 +0100
+++ b/extras/mini-os/console/xencons_ring.c Wed Jul 05 11:27:58 2006 +0100
@@ -53,7 +53,7 @@ int xencons_ring_send(const char *data,
-static void handle_input(int port, struct pt_regs *regs)
+static void handle_input(int port, struct pt_regs *regs, void *ign)
{
struct xencons_interface *intf = xencons_interface();
XENCONS_RING_IDX cons, prod;
@@ -83,7 +83,8 @@ int xencons_ring_init(void)
if (!start_info.console_evtchn)
return 0;
- err = bind_evtchn(start_info.console_evtchn, handle_input);
+ err = bind_evtchn(start_info.console_evtchn, handle_input,
+ NULL);
if (err <= 0) {
printk("XEN console request chn bind failed %i\n", err);
return err;
diff -r 09378a9ca8ad -r 43474e663b3d extras/mini-os/events.c
--- a/extras/mini-os/events.c Wed Jul 05 11:27:25 2006 +0100
+++ b/extras/mini-os/events.c Wed Jul 05 11:27:58 2006 +0100
@@ -22,9 +22,18 @@
#include <events.h>
#include <lib.h>
+#define NR_EVS 1024
+
+/* this represents a event handler. Chaining or sharing is not allowed */
+typedef struct _ev_action_t {
+ void (*handler)(int, struct pt_regs *, void *);
+ void *data;
+ u32 count;
+} ev_action_t;
+
static ev_action_t ev_actions[NR_EVS];
-void default_handler(int port, struct pt_regs *regs);
+void default_handler(int port, struct pt_regs *regs, void *data);
/*
@@ -35,42 +44,33 @@ int do_event(u32 port, struct pt_regs *r
ev_action_t *action;
if (port >= NR_EVS) {
printk("Port number too large: %d\n", port);
- goto out;
+ goto out;
}
action = &ev_actions[port];
action->count++;
- if (!action->handler)
- {
- printk("Spurious event on port %d\n", port);
- goto out;
- }
-
- if (action->status & EVS_DISABLED)
- {
- printk("Event on port %d disabled\n", port);
- goto out;
- }
-
/* call the handler */
- action->handler(port, regs);
-
+ action->handler(port, regs, action->data);
+
out:
clear_evtchn(port);
+
return 1;
}
-int bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *) )
+int bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *, void *),
+ void *data )
{
if(ev_actions[port].handler != default_handler)
printk("WARN: Handler for port %d already registered, replacing\n",
port);
+ ev_actions[port].data = data;
+ wmb();
ev_actions[port].handler = handler;
- ev_actions[port].status &= ~EVS_DISABLED;
-
+
/* Finally unmask the port */
unmask_evtchn(port);
@@ -82,13 +82,14 @@ void unbind_evtchn( u32 port )
if (ev_actions[port].handler == default_handler)
printk("WARN: No handler for port %d when unbinding\n", port);
ev_actions[port].handler = default_handler;
- ev_actions[port].status |= EVS_DISABLED;
+ wmb();
+ ev_actions[port].data = NULL;
}
-int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) )
+int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
+ void *data)
{
evtchn_op_t op;
- int ret = 0;
/* Try to bind the virq to a port */
op.cmd = EVTCHNOP_bind_virq;
@@ -97,13 +98,11 @@ int bind_virq( u32 virq, void (*handler)
if ( HYPERVISOR_event_channel_op(&op) != 0 )
{
- ret = 1;
printk("Failed to bind virtual IRQ %d\n", virq);
- goto out;
+ return 1;
}
- bind_evtchn(op.u.bind_virq.port, handler);
-out:
- return ret;
+ bind_evtchn(op.u.bind_virq.port, handler, data);
+ return 0;
}
void unbind_virq( u32 port )
@@ -137,13 +136,38 @@ void init_events(void)
#endif
/* inintialise event handler */
for ( i = 0; i < NR_EVS; i++ )
- {
- ev_actions[i].status = EVS_DISABLED;
+ {
ev_actions[i].handler = default_handler;
mask_evtchn(i);
}
}
-void default_handler(int port, struct pt_regs *regs) {
+void default_handler(int port, struct pt_regs *regs, void *ignore)
+{
printk("[Port %d] - event received\n", port);
}
+
+/* Unfortunate confusion of terminology: the port is unbound as far
+ as Xen is concerned, but we automatically bind a handler to it
+ from inside mini-os. */
+int evtchn_alloc_unbound(void (*handler)(int, struct pt_regs *regs,
+
void *data),
+ void *data)
+{
+ u32 port;
+ evtchn_op_t op;
+ int err;
+
+ op.cmd = EVTCHNOP_alloc_unbound;
+ op.u.alloc_unbound.dom = DOMID_SELF;
+ op.u.alloc_unbound.remote_dom = 0;
+
+ err = HYPERVISOR_event_channel_op(&op);
+ if (err) {
+ printk("Failed to alloc unbound evtchn: %d.\n", err);
+ return -1;
+ }
+ port = op.u.alloc_unbound.port;
+ bind_evtchn(port, handler, data);
+ return port;
+}
diff -r 09378a9ca8ad -r 43474e663b3d extras/mini-os/include/events.h
--- a/extras/mini-os/include/events.h Wed Jul 05 11:27:25 2006 +0100
+++ b/extras/mini-os/include/events.h Wed Jul 05 11:27:58 2006 +0100
@@ -22,28 +22,18 @@
#include<traps.h>
#include <xen/event_channel.h>
-#define NR_EVS 1024
-
-/* ev handler status */
-#define EVS_INPROGRESS 1 /* Event handler active - do not enter! */
-#define EVS_DISABLED 2 /* Event disabled - do not enter! */
-#define EVS_PENDING 4 /* Event pending - replay on enable */
-#define EVS_REPLAY 8 /* Event has been replayed but not acked yet */
-
-/* this represents a event handler. Chaining or sharing is not allowed */
-typedef struct _ev_action_t {
- void (*handler)(int, struct pt_regs *);
- unsigned int status; /* IRQ status */
- u32 count;
-} ev_action_t;
-
/* prototypes */
int do_event(u32 port, struct pt_regs *regs);
-int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) );
-int bind_evtchn( u32 virq, void (*handler)(int, struct pt_regs *) );
+int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
+ void *data);
+int bind_evtchn( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
+ void *data );
void unbind_evtchn( u32 port );
void init_events(void);
void unbind_virq( u32 port );
+int evtchn_alloc_unbound(void (*handler)(int, struct pt_regs *regs,
+
void *data),
+ void *data);
static inline int notify_remote_via_evtchn(int port)
{
diff -r 09378a9ca8ad -r 43474e663b3d extras/mini-os/include/lib.h
--- a/extras/mini-os/include/lib.h Wed Jul 05 11:27:25 2006 +0100
+++ b/extras/mini-os/include/lib.h Wed Jul 05 11:27:58 2006 +0100
@@ -89,6 +89,7 @@ char *strchr(const char *s, int c);
char *strchr(const char *s, int c);
char *strstr(const char *s1, const char *s2);
char * strcat(char * dest, const char * src);
+char *strdup(const char *s);
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -98,6 +99,18 @@ struct kvec {
size_t iov_len;
};
+#define ASSERT(x) \
+do { \
+ if (!(x)) { \
+ printk("ASSERTION FAILED: %s at %s:%d.\n", \
+ # x , \
+ __FILE__, \
+ __LINE__); \
+ BUG(); \
+ } \
+} while(0)
+/* Consistency check as much as possible. */
+void sanity_check(void);
#endif /* _LIB_H_ */
diff -r 09378a9ca8ad -r 43474e663b3d extras/mini-os/lib/string.c
--- a/extras/mini-os/lib/string.c Wed Jul 05 11:27:25 2006 +0100
+++ b/extras/mini-os/lib/string.c Wed Jul 05 11:27:58 2006 +0100
@@ -23,6 +23,7 @@
#include <os.h>
#include <types.h>
#include <lib.h>
+#include <xmalloc.h>
int memcmp(const void * cs,const void * ct,size_t count)
{
@@ -156,4 +157,13 @@ char * strstr(const char * s1,const char
return NULL;
}
+char *strdup(const char *x)
+{
+ int l = strlen(x);
+ char *res = malloc(l + 1);
+ if (!res) return NULL;
+ memcpy(res, x, l + 1);
+ return res;
+}
+
#endif
diff -r 09378a9ca8ad -r 43474e663b3d extras/mini-os/time.c
--- a/extras/mini-os/time.c Wed Jul 05 11:27:25 2006 +0100
+++ b/extras/mini-os/time.c Wed Jul 05 11:27:58 2006 +0100
@@ -215,7 +215,7 @@ void block_domain(u32 millisecs)
/*
* Just a dummy
*/
-static void timer_handler(int ev, struct pt_regs *regs)
+static void timer_handler(int ev, struct pt_regs *regs, void *ign)
{
static int i;
@@ -233,5 +233,5 @@ void init_time(void)
void init_time(void)
{
printk("Initialising timer interface\n");
- bind_virq(VIRQ_TIMER, &timer_handler);
-}
+ bind_virq(VIRQ_TIMER, &timer_handler, NULL);
+}
diff -r 09378a9ca8ad -r 43474e663b3d extras/mini-os/xenbus/xenbus.c
--- a/extras/mini-os/xenbus/xenbus.c Wed Jul 05 11:27:25 2006 +0100
+++ b/extras/mini-os/xenbus/xenbus.c Wed Jul 05 11:27:58 2006 +0100
@@ -112,7 +112,7 @@ static void xenbus_thread_func(void *ign
}
}
-static void xenbus_evtchn_handler(int port, struct pt_regs *regs)
+static void xenbus_evtchn_handler(int port, struct pt_regs *regs, void *ign)
{
wake_up(&xb_waitq);
}
@@ -174,7 +174,8 @@ void init_xenbus(void)
create_thread("xenstore", xenbus_thread_func, NULL);
DEBUG("buf at %p.\n", xenstore_buf);
err = bind_evtchn(start_info.store_evtchn,
- xenbus_evtchn_handler);
+ xenbus_evtchn_handler,
+ NULL);
DEBUG("xenbus on irq %d\n", err);
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|