ia64/xen-unstable

changeset 10652:43474e663b3d

[MINIOS]Events handling cleaned up. The interface extended to provide
void* pointer to handlers.
Signed-off-by: Steven Smith <sos22@cam.ac.uk>
Signed-off-by: Grzegorz Milos <gm281@cam.ac.uk>
author kfraser@localhost.localdomain
date Wed Jul 05 11:27:58 2006 +0100 (2006-07-05)
parents 09378a9ca8ad
children 5fd332b263d4
files extras/mini-os/console/xencons_ring.c extras/mini-os/events.c extras/mini-os/include/events.h extras/mini-os/include/lib.h extras/mini-os/lib/string.c extras/mini-os/time.c extras/mini-os/xenbus/xenbus.c
line diff
     1.1 --- a/extras/mini-os/console/xencons_ring.c	Wed Jul 05 11:27:25 2006 +0100
     1.2 +++ b/extras/mini-os/console/xencons_ring.c	Wed Jul 05 11:27:58 2006 +0100
     1.3 @@ -53,7 +53,7 @@ int xencons_ring_send(const char *data, 
     1.4  
     1.5  
     1.6  
     1.7 -static void handle_input(int port, struct pt_regs *regs)
     1.8 +static void handle_input(int port, struct pt_regs *regs, void *ign)
     1.9  {
    1.10  	struct xencons_interface *intf = xencons_interface();
    1.11  	XENCONS_RING_IDX cons, prod;
    1.12 @@ -83,7 +83,8 @@ int xencons_ring_init(void)
    1.13  	if (!start_info.console_evtchn)
    1.14  		return 0;
    1.15  
    1.16 -	err = bind_evtchn(start_info.console_evtchn, handle_input);
    1.17 +	err = bind_evtchn(start_info.console_evtchn, handle_input,
    1.18 +			  NULL);
    1.19  	if (err <= 0) {
    1.20  		printk("XEN console request chn bind failed %i\n", err);
    1.21  		return err;
     2.1 --- a/extras/mini-os/events.c	Wed Jul 05 11:27:25 2006 +0100
     2.2 +++ b/extras/mini-os/events.c	Wed Jul 05 11:27:58 2006 +0100
     2.3 @@ -22,9 +22,18 @@
     2.4  #include <events.h>
     2.5  #include <lib.h>
     2.6  
     2.7 +#define NR_EVS 1024
     2.8 +
     2.9 +/* this represents a event handler. Chaining or sharing is not allowed */
    2.10 +typedef struct _ev_action_t {
    2.11 +	void (*handler)(int, struct pt_regs *, void *);
    2.12 +	void *data;
    2.13 +    u32 count;
    2.14 +} ev_action_t;
    2.15 +
    2.16  
    2.17  static ev_action_t ev_actions[NR_EVS];
    2.18 -void default_handler(int port, struct pt_regs *regs);
    2.19 +void default_handler(int port, struct pt_regs *regs, void *data);
    2.20  
    2.21  
    2.22  /*
    2.23 @@ -35,42 +44,33 @@ int do_event(u32 port, struct pt_regs *r
    2.24      ev_action_t  *action;
    2.25      if (port >= NR_EVS) {
    2.26          printk("Port number too large: %d\n", port);
    2.27 -        goto out;
    2.28 +		goto out;
    2.29      }
    2.30  
    2.31      action = &ev_actions[port];
    2.32      action->count++;
    2.33  
    2.34 -    if (!action->handler)
    2.35 -    {
    2.36 -        printk("Spurious event on port %d\n", port);
    2.37 -        goto out;
    2.38 -    }
    2.39 -    
    2.40 -    if (action->status & EVS_DISABLED)
    2.41 -    {
    2.42 -        printk("Event on port %d disabled\n", port);
    2.43 -        goto out;
    2.44 -    }
    2.45 -    
    2.46      /* call the handler */
    2.47 -    action->handler(port, regs);
    2.48 -    
    2.49 +	action->handler(port, regs, action->data);
    2.50 +
    2.51   out:
    2.52  	clear_evtchn(port);
    2.53 +
    2.54      return 1;
    2.55  
    2.56  }
    2.57  
    2.58 -int bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *) )
    2.59 +int bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *, void *),
    2.60 +				 void *data )
    2.61  {
    2.62   	if(ev_actions[port].handler != default_handler)
    2.63          printk("WARN: Handler for port %d already registered, replacing\n",
    2.64  				port);
    2.65  
    2.66 +	ev_actions[port].data = data;
    2.67 +	wmb();
    2.68  	ev_actions[port].handler = handler;
    2.69 -	ev_actions[port].status &= ~EVS_DISABLED;	  
    2.70 - 
    2.71 +
    2.72  	/* Finally unmask the port */
    2.73  	unmask_evtchn(port);
    2.74  
    2.75 @@ -82,13 +82,14 @@ void unbind_evtchn( u32 port )
    2.76  	if (ev_actions[port].handler == default_handler)
    2.77  		printk("WARN: No handler for port %d when unbinding\n", port);
    2.78  	ev_actions[port].handler = default_handler;
    2.79 -	ev_actions[port].status |= EVS_DISABLED;
    2.80 +	wmb();
    2.81 +	ev_actions[port].data = NULL;
    2.82  }
    2.83  
    2.84 -int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) )
    2.85 +int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
    2.86 +			   void *data)
    2.87  {
    2.88  	evtchn_op_t op;
    2.89 -	int ret = 0;
    2.90  
    2.91  	/* Try to bind the virq to a port */
    2.92  	op.cmd = EVTCHNOP_bind_virq;
    2.93 @@ -97,13 +98,11 @@ int bind_virq( u32 virq, void (*handler)
    2.94  
    2.95  	if ( HYPERVISOR_event_channel_op(&op) != 0 )
    2.96  	{
    2.97 -		ret = 1;
    2.98  		printk("Failed to bind virtual IRQ %d\n", virq);
    2.99 -		goto out;
   2.100 +		return 1;
   2.101      }
   2.102 -    bind_evtchn(op.u.bind_virq.port, handler);	
   2.103 -out:
   2.104 -	return ret;
   2.105 +    bind_evtchn(op.u.bind_virq.port, handler, data);
   2.106 +	return 0;
   2.107  }
   2.108  
   2.109  void unbind_virq( u32 port )
   2.110 @@ -137,13 +136,38 @@ void init_events(void)
   2.111  #endif
   2.112      /* inintialise event handler */
   2.113      for ( i = 0; i < NR_EVS; i++ )
   2.114 -    {
   2.115 -        ev_actions[i].status  = EVS_DISABLED;
   2.116 +	{
   2.117          ev_actions[i].handler = default_handler;
   2.118          mask_evtchn(i);
   2.119      }
   2.120  }
   2.121  
   2.122 -void default_handler(int port, struct pt_regs *regs) {
   2.123 +void default_handler(int port, struct pt_regs *regs, void *ignore)
   2.124 +{
   2.125      printk("[Port %d] - event received\n", port);
   2.126  }
   2.127 +
   2.128 +/* Unfortunate confusion of terminology: the port is unbound as far
   2.129 +   as Xen is concerned, but we automatically bind a handler to it
   2.130 +   from inside mini-os. */
   2.131 +int evtchn_alloc_unbound(void (*handler)(int, struct pt_regs *regs,
   2.132 +										 void *data),
   2.133 +						 void *data)
   2.134 +{
   2.135 +	u32 port;
   2.136 +	evtchn_op_t op;
   2.137 +	int err;
   2.138 +
   2.139 +	op.cmd = EVTCHNOP_alloc_unbound;
   2.140 +	op.u.alloc_unbound.dom = DOMID_SELF;
   2.141 +	op.u.alloc_unbound.remote_dom = 0;
   2.142 +
   2.143 +	err = HYPERVISOR_event_channel_op(&op);
   2.144 +	if (err) {
   2.145 +		printk("Failed to alloc unbound evtchn: %d.\n", err);
   2.146 +		return -1;
   2.147 +	}
   2.148 +	port = op.u.alloc_unbound.port;
   2.149 +	bind_evtchn(port, handler, data);
   2.150 +	return port;
   2.151 +}
     3.1 --- a/extras/mini-os/include/events.h	Wed Jul 05 11:27:25 2006 +0100
     3.2 +++ b/extras/mini-os/include/events.h	Wed Jul 05 11:27:58 2006 +0100
     3.3 @@ -22,28 +22,18 @@
     3.4  #include<traps.h>
     3.5  #include <xen/event_channel.h>
     3.6  
     3.7 -#define NR_EVS 1024
     3.8 -
     3.9 -/* ev handler status */
    3.10 -#define EVS_INPROGRESS	1	/* Event handler active - do not enter! */
    3.11 -#define EVS_DISABLED	2	/* Event disabled - do not enter! */
    3.12 -#define EVS_PENDING	    4	/* Event pending - replay on enable */
    3.13 -#define EVS_REPLAY	    8	/* Event has been replayed but not acked yet */
    3.14 -
    3.15 -/* this represents a event handler. Chaining or sharing is not allowed */
    3.16 -typedef struct _ev_action_t {
    3.17 -	void (*handler)(int, struct pt_regs *);
    3.18 -    unsigned int status;		/* IRQ status */
    3.19 -    u32 count;
    3.20 -} ev_action_t;
    3.21 -
    3.22  /* prototypes */
    3.23  int do_event(u32 port, struct pt_regs *regs);
    3.24 -int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) );
    3.25 -int bind_evtchn( u32 virq, void (*handler)(int, struct pt_regs *) );
    3.26 +int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
    3.27 +			   void *data);
    3.28 +int bind_evtchn( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
    3.29 +				 void *data );
    3.30  void unbind_evtchn( u32 port );
    3.31  void init_events(void);
    3.32  void unbind_virq( u32 port );
    3.33 +int evtchn_alloc_unbound(void (*handler)(int, struct pt_regs *regs,
    3.34 +										 void *data),
    3.35 +						 void *data);
    3.36  
    3.37  static inline int notify_remote_via_evtchn(int port)
    3.38  {
     4.1 --- a/extras/mini-os/include/lib.h	Wed Jul 05 11:27:25 2006 +0100
     4.2 +++ b/extras/mini-os/include/lib.h	Wed Jul 05 11:27:58 2006 +0100
     4.3 @@ -89,6 +89,7 @@ size_t strlen(const char *s);
     4.4  char  *strchr(const char *s, int c);
     4.5  char  *strstr(const char *s1, const char *s2);
     4.6  char * strcat(char * dest, const char * src);
     4.7 +char  *strdup(const char *s);
     4.8  
     4.9  
    4.10  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
    4.11 @@ -98,6 +99,18 @@ struct kvec {
    4.12      size_t iov_len;
    4.13  };
    4.14  
    4.15 +#define ASSERT(x)                                              \
    4.16 +do {                                                           \
    4.17 +	if (!(x)) {                                                \
    4.18 +		printk("ASSERTION FAILED: %s at %s:%d.\n",             \
    4.19 +			   # x ,                                           \
    4.20 +			   __FILE__,                                       \
    4.21 +			   __LINE__);                                      \
    4.22 +        BUG();                                                 \
    4.23 +	}                                                          \
    4.24 +} while(0)
    4.25  
    4.26 +/* Consistency check as much as possible. */
    4.27 +void sanity_check(void);
    4.28  
    4.29  #endif /* _LIB_H_ */
     5.1 --- a/extras/mini-os/lib/string.c	Wed Jul 05 11:27:25 2006 +0100
     5.2 +++ b/extras/mini-os/lib/string.c	Wed Jul 05 11:27:58 2006 +0100
     5.3 @@ -23,6 +23,7 @@
     5.4  #include <os.h>
     5.5  #include <types.h>
     5.6  #include <lib.h>
     5.7 +#include <xmalloc.h>
     5.8  
     5.9  int memcmp(const void * cs,const void * ct,size_t count)
    5.10  {
    5.11 @@ -156,4 +157,13 @@ char * strstr(const char * s1,const char
    5.12          return NULL;
    5.13  }
    5.14  
    5.15 +char *strdup(const char *x)
    5.16 +{
    5.17 +    int l = strlen(x);
    5.18 +    char *res = malloc(l + 1);
    5.19 +	if (!res) return NULL;
    5.20 +    memcpy(res, x, l + 1);
    5.21 +    return res;
    5.22 +}
    5.23 +
    5.24  #endif
     6.1 --- a/extras/mini-os/time.c	Wed Jul 05 11:27:25 2006 +0100
     6.2 +++ b/extras/mini-os/time.c	Wed Jul 05 11:27:58 2006 +0100
     6.3 @@ -215,7 +215,7 @@ void block_domain(u32 millisecs)
     6.4  /*
     6.5   * Just a dummy 
     6.6   */
     6.7 -static void timer_handler(int ev, struct pt_regs *regs)
     6.8 +static void timer_handler(int ev, struct pt_regs *regs, void *ign)
     6.9  {
    6.10      static int i;
    6.11  
    6.12 @@ -233,5 +233,5 @@ static void timer_handler(int ev, struct
    6.13  void init_time(void)
    6.14  {
    6.15      printk("Initialising timer interface\n");
    6.16 -    bind_virq(VIRQ_TIMER, &timer_handler);
    6.17 +    bind_virq(VIRQ_TIMER, &timer_handler, NULL);
    6.18  }
     7.1 --- a/extras/mini-os/xenbus/xenbus.c	Wed Jul 05 11:27:25 2006 +0100
     7.2 +++ b/extras/mini-os/xenbus/xenbus.c	Wed Jul 05 11:27:58 2006 +0100
     7.3 @@ -112,7 +112,7 @@ static void xenbus_thread_func(void *ign
     7.4      }
     7.5  }
     7.6  
     7.7 -static void xenbus_evtchn_handler(int port, struct pt_regs *regs)
     7.8 +static void xenbus_evtchn_handler(int port, struct pt_regs *regs, void *ign)
     7.9  {
    7.10      wake_up(&xb_waitq);
    7.11  }
    7.12 @@ -174,7 +174,8 @@ void init_xenbus(void)
    7.13      create_thread("xenstore", xenbus_thread_func, NULL);
    7.14      DEBUG("buf at %p.\n", xenstore_buf);
    7.15      err = bind_evtchn(start_info.store_evtchn,
    7.16 -		      xenbus_evtchn_handler);
    7.17 +		      xenbus_evtchn_handler,
    7.18 +              NULL);
    7.19      DEBUG("xenbus on irq %d\n", err);
    7.20  }
    7.21