aboutsummaryrefslogtreecommitdiffstats
path: root/mini-os/events.c
blob: a2083afa3759df8433d6540ed9367acf6a31e067 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
 ****************************************************************************
 * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
 ****************************************************************************
 *
 *        File: events.c
 *      Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
 *     Changes: 
 *              
 *        Date: Jul 2003
 * 
 * Environment: Xen Minimal OS
 * Description: Deal with events
 *
 ****************************************************************************
 * $Id: c-insert.c,v 1.7 2002/11/08 16:04:34 rn Exp $
 ****************************************************************************
 */

#include <os.h>
#include <hypervisor.h>
#include <events.h>
#include <lib.h>

static ev_action_t ev_actions[NR_EVS];
void default_handler(int ev, struct pt_regs *regs);


/*
 * demux events to different handlers
 */
asmlinkage unsigned int do_event(int ev, struct pt_regs *regs)
{
    ev_action_t  *action;

    if (ev >= NR_EVS) {
        printk("Large event number %d\n", ev);
        return 0;
    }

    action = &ev_actions[ev];
    action->count++;
    ack_hypervisor_event(ev);

    if (!action->handler)
        goto out;
    
    if (action->status & EVS_DISABLED)
        goto out;
    
    /* call the handler */
    action->handler(ev, regs);
    
 out:
    return 1;

}

/*
 * add a handler
 */
unsigned int add_ev_action( int ev, void (*handler)(int, struct pt_regs *) )
{
    if (ev_actions[ev].handler) {
        printk ("event[%d] already handled by %p", ev, ev_actions[ev].handler);
        return 0;
    }

    ev_actions[ev].handler = handler;
    return 1;
}

unsigned int enable_ev_action( int ev )
{
    if (!ev_actions[ev].handler) {
        printk ("enable event[%d], no handler installed", ev);
        return 0;
    }
    ev_actions[ev].status &= ~EVS_DISABLED;
    return 1;
}

unsigned int disable_ev_action( int ev )
{
    ev_actions[ev].status |= EVS_DISABLED;
    return 1;
}

/*
 * initially all events are without a handler and disabled
 */
void init_events(void)
{
    int i;

    /* inintialise event handler */
    for ( i = 0; i < NR_EVS; i++ )
    {
        ev_actions[i].status  = EVS_DISABLED;
        ev_actions[i].handler = NULL;
    }
}

void default_handler(int ev, struct pt_regs *regs) {
    printk("X[%d] ", ev);
}