ia64/xen-unstable

view extras/mini-os/events.c @ 16513:b1da8762f853

blktap: remove unused headers.

Attached patch removes unused linux specific headers
and makes bswap.h ready for BSD support.

This is first step for BSD support in blktap. More to come.
No functional change.

Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Dec 04 10:48:28 2007 +0000 (2007-12-04)
parents e40015e20548
children ea5ee63548e4
line source
1 /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
2 ****************************************************************************
3 * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
4 * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
5 ****************************************************************************
6 *
7 * File: events.c
8 * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
9 * Changes: Grzegorz Milos (gm281@cam.ac.uk)
10 *
11 * Date: Jul 2003, changes Jun 2005
12 *
13 * Environment: Xen Minimal OS
14 * Description: Deals with events recieved on event channels
15 *
16 ****************************************************************************
17 */
19 #include <os.h>
20 #include <mm.h>
21 #include <hypervisor.h>
22 #include <events.h>
23 #include <lib.h>
25 #define NR_EVS 1024
27 /* this represents a event handler. Chaining or sharing is not allowed */
28 typedef struct _ev_action_t {
29 evtchn_handler_t handler;
30 void *data;
31 u32 count;
32 } ev_action_t;
34 static ev_action_t ev_actions[NR_EVS];
35 void default_handler(evtchn_port_t port, struct pt_regs *regs, void *data);
37 static unsigned long bound_ports[NR_EVS/(8*sizeof(unsigned long))];
39 void unbind_all_ports(void)
40 {
41 int i;
43 for (i = 0; i < NR_EVS; i++)
44 {
45 if (test_and_clear_bit(i, bound_ports))
46 {
47 struct evtchn_close close;
48 mask_evtchn(i);
49 close.port = i;
50 HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
51 }
52 }
53 }
55 /*
56 * Demux events to different handlers.
57 */
58 int do_event(evtchn_port_t port, struct pt_regs *regs)
59 {
60 ev_action_t *action;
61 if (port >= NR_EVS) {
62 printk("Port number too large: %d\n", port);
63 goto out;
64 }
66 action = &ev_actions[port];
67 action->count++;
69 /* call the handler */
70 action->handler(port, regs, action->data);
72 out:
73 clear_evtchn(port);
75 return 1;
77 }
79 evtchn_port_t bind_evtchn(evtchn_port_t port, evtchn_handler_t handler,
80 void *data)
81 {
82 if(ev_actions[port].handler != default_handler)
83 printk("WARN: Handler for port %d already registered, replacing\n",
84 port);
86 ev_actions[port].data = data;
87 wmb();
88 ev_actions[port].handler = handler;
90 /* Finally unmask the port */
91 unmask_evtchn(port);
93 return port;
94 }
96 void unbind_evtchn(evtchn_port_t port )
97 {
98 if (ev_actions[port].handler == default_handler)
99 printk("WARN: No handler for port %d when unbinding\n", port);
100 ev_actions[port].handler = default_handler;
101 wmb();
102 ev_actions[port].data = NULL;
103 }
105 evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
106 {
107 evtchn_bind_virq_t op;
109 /* Try to bind the virq to a port */
110 op.virq = virq;
111 op.vcpu = smp_processor_id();
113 if ( HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &op) != 0 )
114 {
115 printk("Failed to bind virtual IRQ %d\n", virq);
116 return -1;
117 }
118 set_bit(op.port,bound_ports);
119 bind_evtchn(op.port, handler, data);
120 return op.port;
121 }
123 #if defined(__x86_64__)
124 /* Allocate 4 pages for the irqstack */
125 #define STACK_PAGES 4
126 char irqstack[1024 * 4 * STACK_PAGES];
128 static struct pda
129 {
130 int irqcount; /* offset 0 (used in x86_64.S) */
131 char *irqstackptr; /* 8 */
132 } cpu0_pda;
133 #endif
135 /*
136 * Initially all events are without a handler and disabled
137 */
138 void init_events(void)
139 {
140 int i;
141 #if defined(__x86_64__)
142 asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
143 wrmsrl(0xc0000101, &cpu0_pda); /* 0xc0000101 is MSR_GS_BASE */
144 cpu0_pda.irqcount = -1;
145 cpu0_pda.irqstackptr = irqstack + 1024 * 4 * STACK_PAGES;
146 #endif
147 /* inintialise event handler */
148 for ( i = 0; i < NR_EVS; i++ )
149 {
150 ev_actions[i].handler = default_handler;
151 mask_evtchn(i);
152 }
153 }
155 void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
156 {
157 printk("[Port %d] - event received\n", port);
158 }
160 /* Create a port available to the pal for exchanging notifications.
161 Returns the result of the hypervisor call. */
163 /* Unfortunate confusion of terminology: the port is unbound as far
164 as Xen is concerned, but we automatically bind a handler to it
165 from inside mini-os. */
167 int evtchn_alloc_unbound(domid_t pal, evtchn_handler_t handler,
168 void *data, evtchn_port_t *port)
169 {
170 evtchn_alloc_unbound_t op;
171 op.dom = DOMID_SELF;
172 op.remote_dom = pal;
173 int err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
174 if (err)
175 return err;
176 *port = bind_evtchn(op.port, handler, data);
177 return err;
178 }
180 /* Connect to a port so as to allow the exchange of notifications with
181 the pal. Returns the result of the hypervisor call. */
183 int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,
184 evtchn_handler_t handler, void *data,
185 evtchn_port_t *local_port)
186 {
187 evtchn_bind_interdomain_t op;
188 op.remote_dom = pal;
189 op.remote_port = remote_port;
190 int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op);
191 if (err)
192 return err;
193 set_bit(op.local_port,bound_ports);
194 evtchn_port_t port = op.local_port;
195 clear_evtchn(port); /* Without, handler gets invoked now! */
196 *local_port = bind_evtchn(port, handler, data);
197 return err;
198 }