ia64/xen-unstable

view xen/common/keyhandler.c @ 11212:ca9f3a7b1b03

[XEN] Remove shadow2 dependencies from common code.
Disable debugtrace functionality even in debug builds:
it's currently only used by shadow2 maintainers.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Aug 18 17:59:26 2006 +0100 (2006-08-18)
parents 0f917d63e960
children a10ef8002af6
line source
1 /******************************************************************************
2 * keyhandler.c
3 */
5 #include <asm/regs.h>
6 #include <xen/keyhandler.h>
7 #include <xen/shutdown.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 <xen/domain.h>
14 #include <xen/rangeset.h>
15 #include <asm/debugger.h>
16 #include <asm/shadow.h>
17 #include <asm/div64.h>
19 #define KEY_MAX 256
20 #define STR_MAX 64
22 static struct {
23 union {
24 keyhandler_t *handler;
25 irq_keyhandler_t *irq_handler;
26 } u;
27 unsigned int flags;
28 char desc[STR_MAX];
29 } key_table[KEY_MAX];
31 #define KEYHANDLER_IRQ_CALLBACK 0x1
33 static unsigned char keypress_key;
35 static void keypress_softirq(void)
36 {
37 keyhandler_t *h;
38 unsigned char key = keypress_key;
39 if ( (h = key_table[key].u.handler) != NULL )
40 (*h)(key);
41 }
43 void handle_keypress(unsigned char key, struct cpu_user_regs *regs)
44 {
45 irq_keyhandler_t *h;
47 if ( key_table[key].flags & KEYHANDLER_IRQ_CALLBACK )
48 {
49 if ( (h = key_table[key].u.irq_handler) != NULL )
50 (*h)(key, regs);
51 }
52 else
53 {
54 keypress_key = key;
55 raise_softirq(KEYPRESS_SOFTIRQ);
56 }
57 }
59 void register_keyhandler(
60 unsigned char key, keyhandler_t *handler, char *desc)
61 {
62 ASSERT(key_table[key].u.handler == NULL);
63 key_table[key].u.handler = handler;
64 key_table[key].flags = 0;
65 strncpy(key_table[key].desc, desc, STR_MAX);
66 key_table[key].desc[STR_MAX-1] = '\0';
67 }
69 void register_irq_keyhandler(
70 unsigned char key, irq_keyhandler_t *handler, char *desc)
71 {
72 ASSERT(key_table[key].u.irq_handler == NULL);
73 key_table[key].u.irq_handler = handler;
74 key_table[key].flags = KEYHANDLER_IRQ_CALLBACK;
75 strncpy(key_table[key].desc, desc, STR_MAX);
76 key_table[key].desc[STR_MAX-1] = '\0';
77 }
79 static void show_handlers(unsigned char key)
80 {
81 int i;
82 printk("'%c' pressed -> showing installed handlers\n", key);
83 for ( i = 0; i < KEY_MAX; i++ )
84 if ( key_table[i].u.handler != NULL )
85 printk(" key '%c' (ascii '%02x') => %s\n",
86 (i<33 || i>126)?(' '):(i),i,
87 key_table[i].desc);
88 }
90 static void __dump_execstate(void *unused)
91 {
92 dump_execution_state();
93 }
95 static void dump_registers(unsigned char key, struct cpu_user_regs *regs)
96 {
97 unsigned int cpu;
99 printk("'%c' pressed -> dumping registers\n", key);
101 /* Get local execution state out immediately, in case we get stuck. */
102 printk("\n*** Dumping CPU%d state: ***\n", smp_processor_id());
103 show_execution_state(regs);
105 for_each_online_cpu ( cpu )
106 {
107 if ( cpu == smp_processor_id() )
108 continue;
109 printk("\n*** Dumping CPU%d state: ***\n", cpu);
110 on_selected_cpus(cpumask_of_cpu(cpu), __dump_execstate, NULL, 1, 1);
111 }
112 }
114 static void halt_machine(unsigned char key, struct cpu_user_regs *regs)
115 {
116 printk("'%c' pressed -> rebooting machine\n", key);
117 machine_restart(NULL);
118 }
120 static void cpuset_print(char *set, int size, cpumask_t mask)
121 {
122 *set++ = '{';
123 set += cpulist_scnprintf(set, size-2, mask);
124 *set++ = '}';
125 *set++ = '\0';
126 }
128 static void dump_domains(unsigned char key)
129 {
130 struct domain *d;
131 struct vcpu *v;
132 s_time_t now = NOW();
133 char cpuset[100];
135 printk("'%c' pressed -> dumping domain info (now=0x%X:%08X)\n", key,
136 (u32)(now>>32), (u32)now);
138 read_lock(&domlist_lock);
140 for_each_domain ( d )
141 {
142 printk("General information for domain %u:\n", d->domain_id);
143 cpuset_print(cpuset, sizeof(cpuset), d->domain_dirty_cpumask);
144 printk(" flags=%lx refcnt=%d nr_pages=%d xenheap_pages=%d "
145 "dirty_cpus=%s\n",
146 d->domain_flags, atomic_read(&d->refcnt),
147 d->tot_pages, d->xenheap_pages, cpuset);
148 printk(" handle=%02x%02x%02x%02x-%02x%02x-%02x%02x-"
149 "%02x%02x-%02x%02x%02x%02x%02x%02x vm_assist=%08lx\n",
150 d->handle[ 0], d->handle[ 1], d->handle[ 2], d->handle[ 3],
151 d->handle[ 4], d->handle[ 5], d->handle[ 6], d->handle[ 7],
152 d->handle[ 8], d->handle[ 9], d->handle[10], d->handle[11],
153 d->handle[12], d->handle[13], d->handle[14], d->handle[15],
154 d->vm_assist);
156 arch_dump_domain_info(d);
158 rangeset_domain_printk(d);
160 dump_pageframe_info(d);
162 printk("VCPU information and callbacks for domain %u:\n",
163 d->domain_id);
164 for_each_vcpu ( d, v ) {
165 printk(" VCPU%d: CPU%d [has=%c] flags=%lx "
166 "upcall_pend = %02x, upcall_mask = %02x ",
167 v->vcpu_id, v->processor,
168 test_bit(_VCPUF_running, &v->vcpu_flags) ? 'T':'F',
169 v->vcpu_flags,
170 v->vcpu_info->evtchn_upcall_pending,
171 v->vcpu_info->evtchn_upcall_mask);
172 cpuset_print(cpuset, sizeof(cpuset), v->vcpu_dirty_cpumask);
173 printk("dirty_cpus=%s ", cpuset);
174 cpuset_print(cpuset, sizeof(cpuset), v->cpu_affinity);
175 printk("cpu_affinity=%s\n", cpuset);
176 printk(" Notifying guest (virq %d, port %d, stat %d/%d/%d)\n",
177 VIRQ_DEBUG, v->virq_to_evtchn[VIRQ_DEBUG],
178 test_bit(v->virq_to_evtchn[VIRQ_DEBUG],
179 d->shared_info->evtchn_pending),
180 test_bit(v->virq_to_evtchn[VIRQ_DEBUG],
181 d->shared_info->evtchn_mask),
182 test_bit(v->virq_to_evtchn[VIRQ_DEBUG]/BITS_PER_LONG,
183 &v->vcpu_info->evtchn_pending_sel));
184 send_guest_vcpu_virq(v, VIRQ_DEBUG);
185 }
186 }
188 read_unlock(&domlist_lock);
189 }
191 static cpumask_t read_clocks_cpumask = CPU_MASK_NONE;
192 static s_time_t read_clocks_time[NR_CPUS];
194 static void read_clocks_slave(void *unused)
195 {
196 unsigned int cpu = smp_processor_id();
197 while ( !cpu_isset(cpu, read_clocks_cpumask) )
198 cpu_relax();
199 read_clocks_time[cpu] = NOW();
200 cpu_clear(cpu, read_clocks_cpumask);
201 }
203 static void read_clocks(unsigned char key)
204 {
205 unsigned int cpu = smp_processor_id(), min_cpu, max_cpu;
206 u64 min, max, dif, difus;
207 static DEFINE_SPINLOCK(lock);
209 spin_lock(&lock);
211 smp_call_function(read_clocks_slave, NULL, 0, 0);
213 local_irq_disable();
214 read_clocks_cpumask = cpu_online_map;
215 read_clocks_time[cpu] = NOW();
216 cpu_clear(cpu, read_clocks_cpumask);
217 local_irq_enable();
219 while ( !cpus_empty(read_clocks_cpumask) )
220 cpu_relax();
222 min_cpu = max_cpu = cpu;
223 for_each_online_cpu ( cpu )
224 {
225 if ( read_clocks_time[cpu] < read_clocks_time[min_cpu] )
226 min_cpu = cpu;
227 if ( read_clocks_time[cpu] > read_clocks_time[max_cpu] )
228 max_cpu = cpu;
229 }
231 min = read_clocks_time[min_cpu];
232 max = read_clocks_time[max_cpu];
234 spin_unlock(&lock);
236 dif = difus = max - min;
237 do_div(difus, 1000);
238 printk("Min = %"PRIu64" ; Max = %"PRIu64" ; Diff = %"PRIu64
239 " (%"PRIu64" microseconds)\n",
240 min, max, dif, difus);
241 }
243 extern void dump_runq(unsigned char key);
245 #ifdef PERF_COUNTERS
246 extern void perfc_printall(unsigned char key);
247 extern void perfc_reset(unsigned char key);
248 #endif
250 static void do_debug_key(unsigned char key, struct cpu_user_regs *regs)
251 {
252 (void)debugger_trap_fatal(0xf001, regs);
253 nop(); /* Prevent the compiler doing tail call
254 optimisation, as that confuses xendbg a
255 bit. */
256 }
258 void initialize_keytable(void)
259 {
260 open_softirq(KEYPRESS_SOFTIRQ, keypress_softirq);
262 register_irq_keyhandler(
263 'd', dump_registers, "dump registers");
264 register_keyhandler(
265 'h', show_handlers, "show this message");
266 register_keyhandler(
267 'q', dump_domains, "dump domain (and guest debug) info");
268 register_keyhandler(
269 'r', dump_runq, "dump run queues");
270 register_irq_keyhandler(
271 'R', halt_machine, "reboot machine");
273 register_keyhandler(
274 't', read_clocks, "display multi-cpu clock info");
276 #ifdef PERF_COUNTERS
277 register_keyhandler(
278 'p', perfc_printall, "print performance counters");
279 register_keyhandler(
280 'P', perfc_reset, "reset performance counters");
281 #endif
283 register_irq_keyhandler('%', do_debug_key, "Trap to xendbg");
284 }
286 /*
287 * Local variables:
288 * mode: C
289 * c-set-style: "BSD"
290 * c-basic-offset: 4
291 * tab-width: 4
292 * indent-tabs-mode: nil
293 * End:
294 */