aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/keyhandler.c
blob: 12fd4e71053dbde514eb145268a39083c80ba308 (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <xeno/keyhandler.h> 
#include <xeno/reboot.h>

extern void perfc_printall (u_char key, void *dev_id, struct pt_regs *regs);

#define KEY_MAX 256
#define STR_MAX  64

typedef struct _key_te { 
    key_handler *handler; 
    char         desc[STR_MAX]; 
} key_te_t; 

static key_te_t key_table[KEY_MAX]; 
    
void add_key_handler(u_char key, key_handler *handler, char *desc) 
{
    int i; 
    char *str; 

    if(key_table[key].handler != NULL) 
    printk("Warning: overwriting handler for key 0x%x\n", key); 

    key_table[key].handler = handler; 

    str = key_table[key].desc; 
    for(i = 0; i < STR_MAX; i++) {
    if(*desc) 
        *str++ = *desc++; 
    else break; 
    }
    if (i == STR_MAX) 
    key_table[key].desc[STR_MAX-1] = '\0'; 

    return; 
}

key_handler *get_key_handler(u_char key)
{
    return key_table[key].handler; 
}


void show_handlers(u_char key, void *dev_id, struct pt_regs *regs) 
{
    int i; 

    printk("'%c' pressed -> showing installed handlers\n", key); 
    for(i=0; i < KEY_MAX; i++) 
    if(key_table[i].handler) 
        printk(" key '%c' (ascii '%02x') => %s\n", 
            (i<33 || i>126)?(' '):(i),i,
            key_table[i].desc);
    return; 
}


void dump_registers(u_char key, void *dev_id, struct pt_regs *regs) 
{
    extern void show_registers(struct pt_regs *regs); 

    printk("'%c' pressed -> dumping registers\n", key); 
    show_registers(regs); 
    return; 
}

void halt_machine(u_char key, void *dev_id, struct pt_regs *regs) 
{
    printk("'%c' pressed -> rebooting machine\n", key); 
    machine_restart(NULL); 
    return; 
}



/* XXX SMH: this is keir's fault */
static char *task_states[] = 
{ 
    "Runnable", 
    "Interruptible Sleep", 
    "Uninterruptible Sleep", 
    NULL, "Stopped", 
    NULL, NULL, NULL, "Dying", 
}; 

void do_task_queues(u_char key, void *dev_id, struct pt_regs *regs) 
{
    u_long flags; 
    struct task_struct *p; 
    shared_info_t *s; 

    printk("'%c' pressed -> dumping task queues\n", key); 
    read_lock_irqsave(&tasklist_lock, flags); 
    p = &idle0_task;
    do {
        printk("Xen: DOM %d, CPU %d [has=%c], state = %s, "
           "hyp_events = %08x\n", 
           p->domain, p->processor, p->has_cpu ? 'T':'F', 
           task_states[p->state], p->hyp_events); 
    s = p->shared_info; 
    if(!is_idle_task(p)) {
        printk("Guest: events = %08lx, event_enable = %08lx\n", 
           s->events, s->events_enable); 
        printk("Notifying guest...\n"); 
        set_bit(_EVENT_DEBUG, &s->events); 
    }
    } while ( (p = p->next_task) != &idle0_task );

    read_unlock_irqrestore(&tasklist_lock, flags); 
}


extern void dump_timerq(u_char key, void *dev_id, struct pt_regs *regs);
extern void dump_runq(u_char key, void *dev_id, struct pt_regs *regs);


void initialize_keytable() 
{
    int i; 

    /* first initialize key handler table */
    for(i = 0; i < KEY_MAX; i++) 
    key_table[i].handler = (key_handler *)NULL; 
    
    /* setup own handlers */
    add_key_handler('a', dump_timerq,    "dump ac_timer queues");
    add_key_handler('d', dump_registers, "dump registers"); 
    add_key_handler('h', show_handlers,  "show this message");
    add_key_handler('p', perfc_printall, "print performance counters"); 
    add_key_handler('q', do_task_queues, "dump task queues + guest state");
    add_key_handler('r', dump_runq,      "dump run queue"); 
    add_key_handler('R', halt_machine,   "reboot machine ungracefully"); 
    
    return; 
}