ia64/xen-unstable

view xen/common/keyhandler.c @ 9776:72f9c751d3ea

Replace &foo[0] with foo where the latter seems cleaner
(which is usually, and particularly when its an argument
to one of the bitops functions).

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Apr 19 18:32:20 2006 +0100 (2006-04-19)
parents 8f7aad20b4a5
children 8aca850f66ad
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),
161 test_bit(v->virq_to_evtchn[VIRQ_DEBUG],
162 d->shared_info->evtchn_mask),
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 */