1 /******************************************************************************
4 * Xenolinux driver for receiving and demuxing event-channel signals.
6 * Copyright (c) 2004, K A Fraser
10 __FBSDID("$FreeBSD$");
12 #include <sys/param.h>
13 #include <sys/systm.h>
16 #include <sys/malloc.h>
17 #include <sys/kernel.h>
19 #include <sys/mutex.h>
20 #include <sys/selinfo.h>
23 #include <sys/fcntl.h>
24 #include <sys/ioccom.h>
27 #include <xen/xen-os.h>
28 #include <xen/evtchn.h>
29 #include <xen/xen_intr.h>
31 #include <machine/bus.h>
32 #include <machine/resource.h>
33 #include <machine/xen/synch_bitops.h>
35 #include <xen/evtchn/evtchnvar.h>
37 typedef struct evtchn_sotfc {
39 struct selinfo ev_rsel;
42 /* Only one process may open /dev/xen/evtchn at any time. */
43 static unsigned long evtchn_dev_inuse;
45 /* Notification ring, accessed via /dev/xen/evtchn. */
47 #define EVTCHN_RING_SIZE 2048 /* 2048 16-bit entries */
49 #define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
50 static uint16_t *ring;
51 static unsigned int ring_cons, ring_prod, ring_overflow;
53 /* Which ports is user-space bound to? */
54 static uint32_t bound_ports[32];
56 /* Unique address for processes to sleep on */
57 static void *evtchn_waddr = ˚
59 static struct mtx lock, upcall_lock;
61 static d_read_t evtchn_read;
62 static d_write_t evtchn_write;
63 static d_ioctl_t evtchn_ioctl;
64 static d_poll_t evtchn_poll;
65 static d_open_t evtchn_open;
66 static d_close_t evtchn_close;
70 evtchn_device_upcall(evtchn_port_t port)
72 mtx_lock(&upcall_lock);
74 evtchn_mask_port(port);
75 evtchn_clear_port(port);
78 if ( (ring_prod - ring_cons) < EVTCHN_RING_SIZE ) {
79 ring[EVTCHN_RING_MASK(ring_prod)] = (uint16_t)port;
80 if ( ring_cons == ring_prod++ ) {
89 mtx_unlock(&upcall_lock);
93 __evtchn_reset_buffer_ring(void)
95 /* Initialise the ring to empty. Clear errors. */
96 ring_cons = ring_prod = ring_overflow = 0;
100 evtchn_read(struct cdev *dev, struct uio *uio, int ioflag)
103 unsigned int count, c, p, sst = 0, bytes1 = 0, bytes2 = 0;
104 count = uio->uio_resid;
106 count &= ~1; /* even number of bytes */
114 if ( count > PAGE_SIZE )
118 if ( (c = ring_cons) != (p = ring_prod) )
121 if ( ring_overflow ) {
131 /* PCATCH == check for signals before and after sleeping
132 * PWAIT == priority of waiting on resource
134 sst = tsleep(evtchn_waddr, PWAIT|PCATCH, "evchwt", 10);
137 /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
138 if ( ((c ^ p) & EVTCHN_RING_SIZE) != 0 ) {
139 bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) * sizeof(uint16_t);
140 bytes2 = EVTCHN_RING_MASK(p) * sizeof(uint16_t);
143 bytes1 = (p - c) * sizeof(uint16_t);
147 /* Truncate chunks according to caller's maximum byte count. */
148 if ( bytes1 > count ) {
152 else if ( (bytes1 + bytes2) > count ) {
153 bytes2 = count - bytes1;
156 if ( uiomove(&ring[EVTCHN_RING_MASK(c)], bytes1, uio) ||
157 ((bytes2 != 0) && uiomove(&ring[0], bytes2, uio)))
158 /* keeping this around as its replacement is not equivalent
159 * copyout(&ring[0], &buf[bytes1], bytes2)
166 ring_cons += (bytes1 + bytes2) / sizeof(uint16_t);
168 rc = bytes1 + bytes2;
176 evtchn_write(struct cdev *dev, struct uio *uio, int ioflag)
180 count = uio->uio_resid;
182 uint16_t *kbuf = (uint16_t *)malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK);
188 count &= ~1; /* even number of bytes */
195 if ( count > PAGE_SIZE )
198 if ( uiomove(kbuf, count, uio) != 0 ) {
203 mtx_lock_spin(&lock);
204 for ( i = 0; i < (count/2); i++ )
205 if ( test_bit(kbuf[i], &bound_ports[0]) )
206 evtchn_unmask_port(kbuf[i]);
207 mtx_unlock_spin(&lock);
212 free(kbuf, M_DEVBUF);
217 evtchn_ioctl(struct cdev *dev, unsigned long cmd, caddr_t arg,
218 int mode, struct thread *td __unused)
223 mtx_lock_spin(&lock);
228 __evtchn_reset_buffer_ring();
231 if ( !synch_test_and_set_bit((uintptr_t)arg, &bound_ports[0]) )
232 unmask_evtchn((uintptr_t)arg);
237 if ( synch_test_and_clear_bit((uintptr_t)arg, &bound_ports[0]) )
238 mask_evtchn((uintptr_t)arg);
247 mtx_unlock_spin(&lock);
254 evtchn_poll(struct cdev *dev, int poll_events, struct thread *td)
258 unsigned int mask = POLLOUT | POLLWRNORM;
262 if ( ring_cons != ring_prod )
263 mask |= POLLIN | POLLRDNORM;
264 else if ( ring_overflow )
267 selrecord(td, &sc->ev_rsel);
275 evtchn_open(struct cdev *dev, int flag, int otyp, struct thread *td)
279 if (flag & O_NONBLOCK)
282 if ( synch_test_and_set_bit(0, &evtchn_dev_inuse) )
285 if ( (_ring = (uint16_t *)malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK)) == NULL )
288 mtx_lock_spin(&lock);
290 __evtchn_reset_buffer_ring();
291 mtx_unlock_spin(&lock);
298 evtchn_close(struct cdev *dev, int flag, int otyp, struct thread *td __unused)
303 free(ring, M_DEVBUF);
306 mtx_lock_spin(&lock);
307 for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
308 if ( synch_test_and_clear_bit(i, &bound_ports[0]) )
310 mtx_unlock_spin(&lock);
312 evtchn_dev_inuse = 0;
317 static struct cdevsw evtchn_devsw = {
318 .d_version = D_VERSION,
319 .d_open = evtchn_open,
320 .d_close = evtchn_close,
321 .d_read = evtchn_read,
322 .d_write = evtchn_write,
323 .d_ioctl = evtchn_ioctl,
324 .d_poll = evtchn_poll,
329 /* XXX - if this device is ever supposed to support use by more than one process
330 * this global static will have to go away
332 static struct cdev *evtchn_dev;
337 evtchn_dev_init(void *dummy __unused)
339 /* XXX I believe we don't need these leaving them here for now until we
340 * have some semblance of it working
342 mtx_init(&upcall_lock, "evtchup", NULL, MTX_DEF);
344 /* (DEVFS) create '/dev/misc/evtchn'. */
345 evtchn_dev = make_dev(&evtchn_devsw, 0, UID_ROOT, GID_WHEEL, 0600, "xen/evtchn");
347 mtx_init(&lock, "evch", NULL, MTX_SPIN | MTX_NOWITNESS);
349 evtchn_dev->si_drv1 = malloc(sizeof(evtchn_softc_t), M_DEVBUF, M_WAITOK);
350 bzero(evtchn_dev->si_drv1, sizeof(evtchn_softc_t));
353 printf("Event-channel device installed.\n");
358 SYSINIT(evtchn_dev_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, evtchn_dev_init, NULL);