ia64/xen-unstable

view xen/common/keyhandler.c @ 9706:3c05406f5e0a

In some cases, say for instance for some bizzare reason
the tree was checked out of CVS, which doens't neccessarily
store file permissions, mkbuildtree may not be executable.
So run them explicitly via bash.

Signed-Off-By: Horms <horms@verge.net.au>
author kaf24@firebug.cl.cam.ac.uk
date Thu Apr 13 11:24:00 2006 +0100 (2006-04-13)
parents 8f7aad20b4a5
children 72f9c751d3ea
line source
1 /******************************************************************************
2 * keyhandler.c
3 */
5 #include <asm/regs.h>
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 <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_registers(unsigned char key, struct cpu_user_regs *regs)
91 {
92 printk("'%c' pressed -> dumping registers\n", key);
93 show_registers(regs);
94 }
96 static void halt_machine(unsigned char key, struct cpu_user_regs *regs)
97 {
98 printk("'%c' pressed -> rebooting machine\n", key);
99 machine_restart(NULL);
100 }
102 static void cpuset_print(char *set, int size, cpumask_t mask)
103 {
104 *set++ = '{';
105 set += cpulist_scnprintf(set, size-2, mask);
106 *set++ = '}';
107 *set++ = '\0';
108 }
110 static void dump_domains(unsigned char key)
111 {
112 struct domain *d;
113 struct vcpu *v;
114 s_time_t now = NOW();
115 char cpuset[100];
117 printk("'%c' pressed -> dumping domain info (now=0x%X:%08X)\n", key,
118 (u32)(now>>32), (u32)now);
120 read_lock(&domlist_lock);
122 for_each_domain ( d )
123 {
124 printk("General information for domain %u:\n", d->domain_id);
125 cpuset_print(cpuset, sizeof(cpuset), d->domain_dirty_cpumask);
126 printk(" flags=%lx refcnt=%d nr_pages=%d xenheap_pages=%d "
127 "dirty_cpus=%s\n",
128 d->domain_flags, atomic_read(&d->refcnt),
129 d->tot_pages, d->xenheap_pages, cpuset);
130 printk(" handle=%02x%02x%02x%02x-%02x%02x-%02x%02x-"
131 "%02x%02x-%02x%02x%02x%02x%02x%02x\n",
132 d->handle[ 0], d->handle[ 1], d->handle[ 2], d->handle[ 3],
133 d->handle[ 4], d->handle[ 5], d->handle[ 6], d->handle[ 7],
134 d->handle[ 8], d->handle[ 9], d->handle[10], d->handle[11],
135 d->handle[12], d->handle[13], d->handle[14], d->handle[15]);
137 arch_dump_domain_info(d);
139 rangeset_domain_printk(d);
141 dump_pageframe_info(d);
143 printk("VCPU information and callbacks for domain %u:\n",
144 d->domain_id);
145 for_each_vcpu ( d, v ) {
146 printk(" VCPU%d: CPU%d [has=%c] flags=%lx "
147 "upcall_pend = %02x, upcall_mask = %02x ",
148 v->vcpu_id, v->processor,
149 test_bit(_VCPUF_running, &v->vcpu_flags) ? 'T':'F',
150 v->vcpu_flags,
151 v->vcpu_info->evtchn_upcall_pending,
152 v->vcpu_info->evtchn_upcall_mask);
153 cpuset_print(cpuset, sizeof(cpuset), v->vcpu_dirty_cpumask);
154 printk("dirty_cpus=%s ", cpuset);
155 cpuset_print(cpuset, sizeof(cpuset), v->cpu_affinity);
156 printk("cpu_affinity=%s\n", cpuset);
157 printk(" Notifying guest (virq %d, port %d, stat %d/%d/%d)\n",
158 VIRQ_DEBUG, v->virq_to_evtchn[VIRQ_DEBUG],
159 test_bit(v->virq_to_evtchn[VIRQ_DEBUG],
160 &d->shared_info->evtchn_pending[0]),
161 test_bit(v->virq_to_evtchn[VIRQ_DEBUG],
162 &d->shared_info->evtchn_mask[0]),
163 test_bit(v->virq_to_evtchn[VIRQ_DEBUG]/BITS_PER_LONG,
164 &v->vcpu_info->evtchn_pending_sel));
165 send_guest_vcpu_virq(v, VIRQ_DEBUG);
166 }
167 }
169 read_unlock(&domlist_lock);
170 }
172 static cpumask_t read_clocks_cpumask = CPU_MASK_NONE;
173 static s_time_t read_clocks_time[NR_CPUS];
175 static void read_clocks_slave(void *unused)
176 {
177 unsigned int cpu = smp_processor_id();
178 while ( !cpu_isset(cpu, read_clocks_cpumask) )
179 cpu_relax();
180 read_clocks_time[cpu] = NOW();
181 cpu_clear(cpu, read_clocks_cpumask);
182 }
184 static void read_clocks(unsigned char key)
185 {
186 unsigned int cpu = smp_processor_id(), min_cpu, max_cpu;
187 u64 min, max, dif, difus;
188 static DEFINE_SPINLOCK(lock);
190 spin_lock(&lock);
192 smp_call_function(read_clocks_slave, NULL, 0, 0);
194 local_irq_disable();
195 read_clocks_cpumask = cpu_online_map;
196 read_clocks_time[cpu] = NOW();
197 cpu_clear(cpu, read_clocks_cpumask);
198 local_irq_enable();
200 while ( !cpus_empty(read_clocks_cpumask) )
201 cpu_relax();
203 min_cpu = max_cpu = cpu;
204 for_each_online_cpu ( cpu )
205 {
206 if ( read_clocks_time[cpu] < read_clocks_time[min_cpu] )
207 min_cpu = cpu;
208 if ( read_clocks_time[cpu] > read_clocks_time[max_cpu] )
209 max_cpu = cpu;
210 }
212 min = read_clocks_time[min_cpu];
213 max = read_clocks_time[max_cpu];
215 spin_unlock(&lock);
217 dif = difus = max - min;
218 do_div(difus, 1000);
219 printk("Min = %"PRIu64" ; Max = %"PRIu64" ; Diff = %"PRIu64
220 " (%"PRIu64" microseconds)\n",
221 min, max, dif, difus);
222 }
224 extern void dump_runq(unsigned char key);
225 #ifndef NDEBUG
226 extern void audit_domains_key(unsigned char key);
227 #endif
229 #ifdef PERF_COUNTERS
230 extern void perfc_printall(unsigned char key);
231 extern void perfc_reset(unsigned char key);
232 #endif
234 static void do_debug_key(unsigned char key, struct cpu_user_regs *regs)
235 {
236 (void)debugger_trap_fatal(0xf001, regs);
237 nop(); /* Prevent the compiler doing tail call
238 optimisation, as that confuses xendbg a
239 bit. */
240 }
242 #ifndef NDEBUG
243 static void debugtrace_key(unsigned char key)
244 {
245 debugtrace_send_to_console = !debugtrace_send_to_console;
246 debugtrace_dump();
247 printk("debugtrace_printk now writing to %s.\n",
248 debugtrace_send_to_console ? "console" : "buffer");
249 }
250 #endif
252 void initialize_keytable(void)
253 {
254 open_softirq(KEYPRESS_SOFTIRQ, keypress_softirq);
256 register_irq_keyhandler(
257 'd', dump_registers, "dump registers");
258 register_keyhandler(
259 'h', show_handlers, "show this message");
260 register_keyhandler(
261 'q', dump_domains, "dump domain (and guest debug) info");
262 register_keyhandler(
263 'r', dump_runq, "dump run queues");
264 register_irq_keyhandler(
265 'R', halt_machine, "reboot machine");
267 register_keyhandler(
268 't', read_clocks, "display multi-cpu clock info");
270 #ifndef NDEBUG
271 register_keyhandler(
272 'o', audit_domains_key, "audit domains >0 EXPERIMENTAL");
273 register_keyhandler(
274 'T', debugtrace_key, "toggle debugtrace to console/buffer");
275 #endif
277 #ifdef PERF_COUNTERS
278 register_keyhandler(
279 'p', perfc_printall, "print performance counters");
280 register_keyhandler(
281 'P', perfc_reset, "reset performance counters");
282 #endif
284 register_irq_keyhandler('%', do_debug_key, "Trap to xendbg");
285 }
287 /*
288 * Local variables:
289 * mode: C
290 * c-set-style: "BSD"
291 * c-basic-offset: 4
292 * tab-width: 4
293 * indent-tabs-mode: nil
294 * End:
295 */