ia64/xen-unstable

annotate extras/mini-os/events.c @ 10848:a10d02d20b31

[MINI-OS] unbind_virq is broken and nobody uses it. Remove it.

Signed-off-by: Steven Smith <sos22@cam.ac.uk>
author sos22@douglas.cl.cam.ac.uk
date Fri Jul 28 14:00:37 2006 +0100 (2006-07-28)
parents 43474e663b3d
children 98a802d25848
rev   line source
iap10@792 1 /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
iap10@792 2 ****************************************************************************
iap10@792 3 * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
kaf24@5675 4 * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
iap10@792 5 ****************************************************************************
iap10@792 6 *
iap10@792 7 * File: events.c
iap10@792 8 * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
kaf24@5675 9 * Changes: Grzegorz Milos (gm281@cam.ac.uk)
iap10@792 10 *
kaf24@5675 11 * Date: Jul 2003, changes Jun 2005
iap10@792 12 *
iap10@792 13 * Environment: Xen Minimal OS
kaf24@5675 14 * Description: Deals with events recieved on event channels
iap10@792 15 *
iap10@792 16 ****************************************************************************
iap10@792 17 */
iap10@792 18
iap10@792 19 #include <os.h>
kaf24@6714 20 #include <mm.h>
iap10@792 21 #include <hypervisor.h>
iap10@792 22 #include <events.h>
iap10@792 23 #include <lib.h>
iap10@792 24
kfraser@10652 25 #define NR_EVS 1024
kfraser@10652 26
kfraser@10652 27 /* this represents a event handler. Chaining or sharing is not allowed */
kfraser@10652 28 typedef struct _ev_action_t {
kfraser@10652 29 void (*handler)(int, struct pt_regs *, void *);
kfraser@10652 30 void *data;
kfraser@10652 31 u32 count;
kfraser@10652 32 } ev_action_t;
kfraser@10652 33
kaf24@9298 34
iap10@792 35 static ev_action_t ev_actions[NR_EVS];
kfraser@10652 36 void default_handler(int port, struct pt_regs *regs, void *data);
iap10@792 37
iap10@792 38
iap10@792 39 /*
kaf24@5675 40 * Demux events to different handlers.
iap10@792 41 */
kaf24@5675 42 int do_event(u32 port, struct pt_regs *regs)
iap10@792 43 {
iap10@792 44 ev_action_t *action;
kaf24@5675 45 if (port >= NR_EVS) {
kaf24@5675 46 printk("Port number too large: %d\n", port);
kfraser@10652 47 goto out;
iap10@792 48 }
iap10@792 49
kaf24@5675 50 action = &ev_actions[port];
iap10@792 51 action->count++;
iap10@792 52
iap10@792 53 /* call the handler */
kfraser@10652 54 action->handler(port, regs, action->data);
kfraser@10652 55
iap10@792 56 out:
kaf24@10412 57 clear_evtchn(port);
kfraser@10652 58
iap10@792 59 return 1;
iap10@792 60
iap10@792 61 }
iap10@792 62
kfraser@10652 63 int bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *, void *),
kfraser@10652 64 void *data )
kaf24@6714 65 {
kaf24@9298 66 if(ev_actions[port].handler != default_handler)
kaf24@6714 67 printk("WARN: Handler for port %d already registered, replacing\n",
kaf24@6714 68 port);
kaf24@6714 69
kfraser@10652 70 ev_actions[port].data = data;
kfraser@10652 71 wmb();
kaf24@6714 72 ev_actions[port].handler = handler;
kfraser@10652 73
kaf24@6714 74 /* Finally unmask the port */
kaf24@6714 75 unmask_evtchn(port);
kaf24@8284 76
kaf24@8284 77 return port;
kaf24@8284 78 }
kaf24@8284 79
kaf24@8284 80 void unbind_evtchn( u32 port )
kaf24@8284 81 {
kaf24@9444 82 if (ev_actions[port].handler == default_handler)
kaf24@8284 83 printk("WARN: No handler for port %d when unbinding\n", port);
kaf24@9444 84 ev_actions[port].handler = default_handler;
kfraser@10652 85 wmb();
kfraser@10652 86 ev_actions[port].data = NULL;
kaf24@6714 87 }
kaf24@6714 88
kfraser@10652 89 int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
kfraser@10652 90 void *data)
iap10@792 91 {
kaf24@5675 92 evtchn_op_t op;
kaf24@5675 93
kaf24@5675 94 /* Try to bind the virq to a port */
kaf24@5675 95 op.cmd = EVTCHNOP_bind_virq;
kaf24@5675 96 op.u.bind_virq.virq = virq;
kaf24@8251 97 op.u.bind_virq.vcpu = smp_processor_id();
kaf24@5675 98
kaf24@5675 99 if ( HYPERVISOR_event_channel_op(&op) != 0 )
kaf24@5675 100 {
kaf24@5675 101 printk("Failed to bind virtual IRQ %d\n", virq);
kfraser@10652 102 return 1;
iap10@792 103 }
kfraser@10652 104 bind_evtchn(op.u.bind_virq.port, handler, data);
kfraser@10652 105 return 0;
iap10@792 106 }
iap10@792 107
kaf24@9911 108 #if defined(__x86_64__)
kaf24@9911 109 /* Allocate 4 pages for the irqstack */
kaf24@9911 110 #define STACK_PAGES 4
kaf24@9911 111 char irqstack[1024 * 4 * STACK_PAGES];
kaf24@9911 112
kaf24@9911 113 static struct pda
kaf24@9911 114 {
kaf24@9911 115 int irqcount; /* offset 0 (used in x86_64.S) */
kaf24@9911 116 char *irqstackptr; /* 8 */
kaf24@9911 117 } cpu0_pda;
kaf24@9911 118 #endif
kaf24@6714 119
iap10@792 120 /*
kaf24@5675 121 * Initially all events are without a handler and disabled
iap10@792 122 */
iap10@792 123 void init_events(void)
iap10@792 124 {
iap10@792 125 int i;
kaf24@9911 126 #if defined(__x86_64__)
kaf24@9911 127 asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
kaf24@9911 128 wrmsrl(0xc0000101, &cpu0_pda); /* 0xc0000101 is MSR_GS_BASE */
kaf24@9911 129 cpu0_pda.irqcount = -1;
kaf24@9911 130 cpu0_pda.irqstackptr = irqstack + 1024 * 4 * STACK_PAGES;
kaf24@9911 131 #endif
iap10@792 132 /* inintialise event handler */
iap10@792 133 for ( i = 0; i < NR_EVS; i++ )
kfraser@10652 134 {
kaf24@6714 135 ev_actions[i].handler = default_handler;
kaf24@10412 136 mask_evtchn(i);
iap10@792 137 }
iap10@792 138 }
iap10@792 139
kfraser@10652 140 void default_handler(int port, struct pt_regs *regs, void *ignore)
kfraser@10652 141 {
kaf24@5675 142 printk("[Port %d] - event received\n", port);
iap10@792 143 }
kfraser@10652 144
kfraser@10652 145 /* Unfortunate confusion of terminology: the port is unbound as far
kfraser@10652 146 as Xen is concerned, but we automatically bind a handler to it
kfraser@10652 147 from inside mini-os. */
kfraser@10652 148 int evtchn_alloc_unbound(void (*handler)(int, struct pt_regs *regs,
kfraser@10652 149 void *data),
kfraser@10652 150 void *data)
kfraser@10652 151 {
kfraser@10652 152 u32 port;
kfraser@10652 153 evtchn_op_t op;
kfraser@10652 154 int err;
kfraser@10652 155
kfraser@10652 156 op.cmd = EVTCHNOP_alloc_unbound;
kfraser@10652 157 op.u.alloc_unbound.dom = DOMID_SELF;
kfraser@10652 158 op.u.alloc_unbound.remote_dom = 0;
kfraser@10652 159
kfraser@10652 160 err = HYPERVISOR_event_channel_op(&op);
kfraser@10652 161 if (err) {
kfraser@10652 162 printk("Failed to alloc unbound evtchn: %d.\n", err);
kfraser@10652 163 return -1;
kfraser@10652 164 }
kfraser@10652 165 port = op.u.alloc_unbound.port;
kfraser@10652 166 bind_evtchn(port, handler, data);
kfraser@10652 167 return port;
kfraser@10652 168 }