ia64/xen-unstable

view xen/common/keyhandler.c @ 3883:2fd53607c7ee

bitkeeper revision 1.1230.2.1 (421a871fZOwVkDnyTbM9miM9F5Em1g)

Avoid pulling in more header files (again).
Signed-off-by: chris@xensource.com
author cl349@arcadians.cl.cam.ac.uk
date Tue Feb 22 01:13:03 2005 +0000 (2005-02-22)
parents ffb2d7ac4b7f
children ff8c9a2be5f7
line source
1 /* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
2 /******************************************************************************
3 * keyhandler.c
4 */
6 #include <asm/regs.h>
7 #include <xen/keyhandler.h>
8 #include <xen/reboot.h>
9 #include <xen/event.h>
10 #include <xen/console.h>
11 #include <xen/serial.h>
12 #include <xen/sched.h>
13 #include <xen/softirq.h>
14 #include <asm/debugger.h>
16 #define KEY_MAX 256
17 #define STR_MAX 64
19 static struct {
20 union {
21 keyhandler_t *handler;
22 irq_keyhandler_t *irq_handler;
23 } u;
24 unsigned int flags;
25 char desc[STR_MAX];
26 } key_table[KEY_MAX];
28 #define KEYHANDLER_IRQ_CALLBACK 0x1
30 static unsigned char keypress_key;
32 static void keypress_softirq(void)
33 {
34 keyhandler_t *h;
35 unsigned char key = keypress_key;
36 if ( (h = key_table[key].u.handler) != NULL )
37 (*h)(key);
38 }
40 void handle_keypress(unsigned char key, struct xen_regs *regs)
41 {
42 irq_keyhandler_t *h;
44 if ( key_table[key].flags & KEYHANDLER_IRQ_CALLBACK )
45 {
46 if ( (h = key_table[key].u.irq_handler) != NULL )
47 (*h)(key, regs);
48 }
49 else
50 {
51 keypress_key = key;
52 raise_softirq(KEYPRESS_SOFTIRQ);
53 }
54 }
56 void register_keyhandler(
57 unsigned char key, keyhandler_t *handler, char *desc)
58 {
59 ASSERT(key_table[key].u.handler == NULL);
60 key_table[key].u.handler = handler;
61 key_table[key].flags = 0;
62 strncpy(key_table[key].desc, desc, STR_MAX);
63 key_table[key].desc[STR_MAX-1] = '\0';
64 }
66 void register_irq_keyhandler(
67 unsigned char key, irq_keyhandler_t *handler, char *desc)
68 {
69 ASSERT(key_table[key].u.irq_handler == NULL);
70 key_table[key].u.irq_handler = handler;
71 key_table[key].flags = KEYHANDLER_IRQ_CALLBACK;
72 strncpy(key_table[key].desc, desc, STR_MAX);
73 key_table[key].desc[STR_MAX-1] = '\0';
74 }
76 static void show_handlers(unsigned char key)
77 {
78 int i;
79 printk("'%c' pressed -> showing installed handlers\n", key);
80 for ( i = 0; i < KEY_MAX; i++ )
81 if ( key_table[i].u.handler != NULL )
82 printk(" key '%c' (ascii '%02x') => %s\n",
83 (i<33 || i>126)?(' '):(i),i,
84 key_table[i].desc);
85 }
87 static void dump_registers(unsigned char key, struct xen_regs *regs)
88 {
89 printk("'%c' pressed -> dumping registers\n", key);
90 show_registers(regs);
91 }
93 static void halt_machine(unsigned char key, struct xen_regs *regs)
94 {
95 printk("'%c' pressed -> rebooting machine\n", key);
96 machine_restart(NULL);
97 }
99 static void do_task_queues(unsigned char key)
100 {
101 struct domain *d;
102 struct exec_domain *ed;
103 s_time_t now = NOW();
105 printk("'%c' pressed -> dumping task queues (now=0x%X:%08X)\n", key,
106 (u32)(now>>32), (u32)now);
108 read_lock(&domlist_lock);
110 for_each_domain ( d )
111 {
112 printk("Xen: DOM %u, flags=%lx refcnt=%d nr_pages=%d "
113 "xenheap_pages=%d\n", d->id, d->d_flags,
114 atomic_read(&d->refcnt), d->tot_pages, d->xenheap_pages);
116 dump_pageframe_info(d);
118 for_each_exec_domain ( d, ed ) {
119 printk("Guest: %p CPU %d [has=%c] flags=%lx "
120 "upcall_pend = %02x, upcall_mask = %02x\n", ed,
121 ed->processor,
122 test_bit(EDF_RUNNING, &ed->ed_flags) ? 'T':'F',
123 ed->ed_flags,
124 ed->vcpu_info->evtchn_upcall_pending,
125 ed->vcpu_info->evtchn_upcall_mask);
126 printk("Notifying guest... %d/%d\n", d->id, ed->eid);
127 printk("port %d/%d stat %d %d %d\n",
128 VIRQ_DEBUG, ed->virq_to_evtchn[VIRQ_DEBUG],
129 test_bit(ed->virq_to_evtchn[VIRQ_DEBUG], &d->shared_info->evtchn_pending[0]),
130 test_bit(ed->virq_to_evtchn[VIRQ_DEBUG], &d->shared_info->evtchn_mask[0]),
131 test_bit(ed->virq_to_evtchn[VIRQ_DEBUG]>>5, &ed->vcpu_info->evtchn_pending_sel));
132 send_guest_virq(ed, VIRQ_DEBUG);
133 }
134 }
136 read_unlock(&domlist_lock);
137 }
139 extern void dump_runq(unsigned char key);
140 extern void print_sched_histo(unsigned char key);
141 extern void reset_sched_histo(unsigned char key);
142 #ifndef NDEBUG
143 extern void audit_domains_key(unsigned char key);
144 #endif
146 #ifdef PERF_COUNTERS
147 extern void perfc_printall(unsigned char key);
148 extern void perfc_reset(unsigned char key);
149 #endif
151 void do_debug_key(unsigned char key, struct xen_regs *regs)
152 {
153 (void)debugger_trap_fatal(0xf001, regs);
154 nop(); /* Prevent the compiler doing tail call
155 optimisation, as that confuses xendbg a
156 bit. */
157 }
159 #ifndef NDEBUG
160 void debugtrace_key(unsigned char key)
161 {
162 debugtrace_send_to_console = !debugtrace_send_to_console;
163 debugtrace_dump();
164 printk("debugtrace_printk now writing to %s.\n",
165 debugtrace_send_to_console ? "console" : "buffer");
166 }
167 #endif
169 void initialize_keytable(void)
170 {
171 open_softirq(KEYPRESS_SOFTIRQ, keypress_softirq);
173 register_irq_keyhandler(
174 'd', dump_registers, "dump registers");
175 register_keyhandler(
176 'h', show_handlers, "show this message");
177 register_keyhandler(
178 'l', print_sched_histo, "print sched latency histogram");
179 register_keyhandler(
180 'L', reset_sched_histo, "reset sched latency histogram");
181 register_keyhandler(
182 'q', do_task_queues, "dump task queues + guest state");
183 register_keyhandler(
184 'r', dump_runq, "dump run queues");
185 register_irq_keyhandler(
186 'R', halt_machine, "reboot machine");
188 #ifndef NDEBUG
189 register_keyhandler(
190 'o', audit_domains_key, "audit domains >0 EXPERIMENTAL");
191 register_keyhandler(
192 'T', debugtrace_key, "dump debugtrace");
193 #endif
195 #ifdef PERF_COUNTERS
196 register_keyhandler(
197 'p', perfc_printall, "print performance counters");
198 register_keyhandler(
199 'P', perfc_reset, "reset performance counters");
200 #endif
202 register_irq_keyhandler('%', do_debug_key, "Trap to xendbg");
203 }