ia64/xen-unstable

view xen/common/keyhandler.c @ 3776:d9449b5a8d64

bitkeeper revision 1.1170.1.1 (420b98f5HLKkq19C9PxLpNFZOD2-mg)

Make it compile in the non-crash_debug case.
author sos22@douglas.cl.cam.ac.uk
date Thu Feb 10 17:25:09 2005 +0000 (2005-02-10)
parents 415d774d6ee7
children c37c674174f7
line source
1 /* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
2 /******************************************************************************
3 * keyhandler.c
4 */
6 #include <xen/keyhandler.h>
7 #include <xen/reboot.h>
8 #include <xen/event.h>
9 #include <xen/console.h>
10 #include <xen/serial.h>
11 #include <xen/sched.h>
12 #include <xen/softirq.h>
13 #include <asm/debugger.h>
15 #define KEY_MAX 256
16 #define STR_MAX 64
18 static struct {
19 union {
20 keyhandler_t *handler;
21 irq_keyhandler_t *irq_handler;
22 } u;
23 unsigned int flags;
24 char desc[STR_MAX];
25 } key_table[KEY_MAX];
27 #define KEYHANDLER_IRQ_CALLBACK 0x1
29 static unsigned char keypress_key;
31 static void keypress_softirq(void)
32 {
33 keyhandler_t *h;
34 unsigned char key = keypress_key;
35 if ( (h = key_table[key].u.handler) != NULL )
36 (*h)(key);
37 }
39 void handle_keypress(unsigned char key, struct xen_regs *regs)
40 {
41 irq_keyhandler_t *h;
43 if ( key_table[key].flags & KEYHANDLER_IRQ_CALLBACK )
44 {
45 if ( (h = key_table[key].u.irq_handler) != NULL )
46 (*h)(key, regs);
47 }
48 else
49 {
50 keypress_key = key;
51 raise_softirq(KEYPRESS_SOFTIRQ);
52 }
53 }
55 void register_keyhandler(
56 unsigned char key, keyhandler_t *handler, char *desc)
57 {
58 ASSERT(key_table[key].u.handler == NULL);
59 key_table[key].u.handler = handler;
60 key_table[key].flags = 0;
61 strncpy(key_table[key].desc, desc, STR_MAX);
62 key_table[key].desc[STR_MAX-1] = '\0';
63 }
65 void register_irq_keyhandler(
66 unsigned char key, irq_keyhandler_t *handler, char *desc)
67 {
68 ASSERT(key_table[key].u.irq_handler == NULL);
69 key_table[key].u.irq_handler = handler;
70 key_table[key].flags = KEYHANDLER_IRQ_CALLBACK;
71 strncpy(key_table[key].desc, desc, STR_MAX);
72 key_table[key].desc[STR_MAX-1] = '\0';
73 }
75 static void show_handlers(unsigned char key)
76 {
77 int i;
78 printk("'%c' pressed -> showing installed handlers\n", key);
79 for ( i = 0; i < KEY_MAX; i++ )
80 if ( key_table[i].u.handler != NULL )
81 printk(" key '%c' (ascii '%02x') => %s\n",
82 (i<33 || i>126)?(' '):(i),i,
83 key_table[i].desc);
84 }
86 static void dump_registers(unsigned char key, struct xen_regs *regs)
87 {
88 printk("'%c' pressed -> dumping registers\n", key);
89 show_registers(regs);
90 }
92 static void halt_machine(unsigned char key, struct xen_regs *regs)
93 {
94 printk("'%c' pressed -> rebooting machine\n", key);
95 machine_restart(NULL);
96 }
98 static void do_task_queues(unsigned char key)
99 {
100 struct domain *d;
101 struct exec_domain *ed;
102 s_time_t now = NOW();
104 printk("'%c' pressed -> dumping task queues (now=0x%X:%08X)\n", key,
105 (u32)(now>>32), (u32)now);
107 read_lock(&domlist_lock);
109 for_each_domain ( d )
110 {
111 printk("Xen: DOM %u, flags=%lx refcnt=%d nr_pages=%d "
112 "xenheap_pages=%d\n", d->id, d->d_flags,
113 atomic_read(&d->refcnt), d->tot_pages, d->xenheap_pages);
115 dump_pageframe_info(d);
117 for_each_exec_domain ( d, ed ) {
118 printk("Guest: %p CPU %d [has=%c] flags=%lx "
119 "upcall_pend = %02x, upcall_mask = %02x\n", ed,
120 ed->processor,
121 test_bit(EDF_RUNNING, &ed->ed_flags) ? 'T':'F',
122 ed->ed_flags,
123 ed->vcpu_info->evtchn_upcall_pending,
124 ed->vcpu_info->evtchn_upcall_mask);
125 printk("Notifying guest... %d/%d\n", d->id, ed->eid);
126 printk("port %d/%d stat %d %d %d\n",
127 VIRQ_DEBUG, ed->virq_to_evtchn[VIRQ_DEBUG],
128 test_bit(ed->virq_to_evtchn[VIRQ_DEBUG], &d->shared_info->evtchn_pending[0]),
129 test_bit(ed->virq_to_evtchn[VIRQ_DEBUG], &d->shared_info->evtchn_mask[0]),
130 test_bit(ed->virq_to_evtchn[VIRQ_DEBUG]>>5, &ed->vcpu_info->evtchn_pending_sel));
131 send_guest_virq(ed, VIRQ_DEBUG);
132 }
133 }
135 read_unlock(&domlist_lock);
136 }
138 extern void dump_runq(unsigned char key);
139 extern void print_sched_histo(unsigned char key);
140 extern void reset_sched_histo(unsigned char key);
141 #ifndef NDEBUG
142 extern void audit_domains_key(unsigned char key);
143 #endif
145 #ifdef PERF_COUNTERS
146 extern void perfc_printall(unsigned char key);
147 extern void perfc_reset(unsigned char key);
148 #endif
150 void do_debug_key(unsigned char key, struct xen_regs *regs)
151 {
152 (void)debugger_trap_fatal(0xf001, regs);
153 asm volatile ("nop"); /* Prevent the compiler doing tail call
154 optimisation, as that confuses xendbg a
155 bit. */
156 }
158 void initialize_keytable(void)
159 {
160 open_softirq(KEYPRESS_SOFTIRQ, keypress_softirq);
162 register_irq_keyhandler(
163 'd', dump_registers, "dump registers");
164 register_keyhandler(
165 'h', show_handlers, "show this message");
166 register_keyhandler(
167 'l', print_sched_histo, "print sched latency histogram");
168 register_keyhandler(
169 'L', reset_sched_histo, "reset sched latency histogram");
170 register_keyhandler(
171 'q', do_task_queues, "dump task queues + guest state");
172 register_keyhandler(
173 'r', dump_runq, "dump run queues");
174 register_irq_keyhandler(
175 'R', halt_machine, "reboot machine");
177 #ifndef NDEBUG
178 register_keyhandler(
179 'o', audit_domains_key, "audit domains >0 EXPERIMENTAL");
180 #endif
182 #ifdef PERF_COUNTERS
183 register_keyhandler(
184 'p', perfc_printall, "print performance counters");
185 register_keyhandler(
186 'P', perfc_reset, "reset performance counters");
187 #endif
188 register_irq_keyhandler('%', do_debug_key, "Trap to xendbg");
189 }