blob: 6b7ce432a31d4a270dd818fef9a2aa7b202ed497 [file] [log] [blame]
Iliyan Malchevc1db50b2010-06-05 17:36:24 -07001/*
2 * arch/arm/common/fiq_debugger.c
3 *
4 * Serial Debugger Interface accessed through an FIQ interrupt.
5 *
6 * Copyright (C) 2008 Google, Inc.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <stdarg.h>
19#include <linux/module.h>
20#include <linux/io.h>
Colin Cross4df8d7b2010-08-16 14:51:51 -070021#include <linux/console.h>
Iliyan Malchevc1db50b2010-06-05 17:36:24 -070022#include <linux/interrupt.h>
23#include <linux/clk.h>
24#include <linux/platform_device.h>
25#include <linux/kernel_debugger.h>
26#include <linux/kernel_stat.h>
27#include <linux/irq.h>
28#include <linux/delay.h>
29#include <linux/sched.h>
30#include <linux/slab.h>
31#include <linux/timer.h>
Colin Cross4df8d7b2010-08-16 14:51:51 -070032#include <linux/tty.h>
33#include <linux/tty_flip.h>
Iliyan Malchevc1db50b2010-06-05 17:36:24 -070034#include <linux/wakelock.h>
35
36#include <asm/fiq_debugger.h>
37#include <asm/fiq_glue.h>
38#include <asm/stacktrace.h>
39
40#include <mach/system.h>
41
42#include <linux/uaccess.h>
43
Colin Cross4df8d7b2010-08-16 14:51:51 -070044#include "fiq_debugger_ringbuf.h"
45
Iliyan Malchevc1db50b2010-06-05 17:36:24 -070046#define DEBUG_MAX 64
Colin Cross24b3bd42010-10-01 23:41:38 -070047#define MAX_UNHANDLED_FIQ_COUNT 1000000
48
49#define THREAD_INFO(sp) ((struct thread_info *) \
50 ((unsigned long)(sp) & ~(THREAD_SIZE - 1)))
Iliyan Malchevc1db50b2010-06-05 17:36:24 -070051
52struct fiq_debugger_state {
53 struct fiq_glue_handler handler;
54
55 int fiq;
56 int signal_irq;
57 int wakeup_irq;
58 bool wakeup_irq_no_set_wake;
59 struct clk *clk;
60 struct fiq_debugger_pdata *pdata;
61 struct platform_device *pdev;
62
63 char debug_cmd[DEBUG_MAX];
64 int debug_busy;
65 int debug_abort;
66
67 char debug_buf[DEBUG_MAX];
68 int debug_count;
69
70 bool no_sleep;
71 bool debug_enable;
72 bool ignore_next_wakeup_irq;
73 struct timer_list sleep_timer;
74 bool uart_clk_enabled;
75 struct wake_lock debugger_wake_lock;
Colin Cross4df8d7b2010-08-16 14:51:51 -070076 bool console_enable;
Colin Cross24b3bd42010-10-01 23:41:38 -070077 int current_cpu;
78 atomic_t unhandled_fiq_count;
79 bool in_fiq;
Colin Cross4df8d7b2010-08-16 14:51:51 -070080
81#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE
82 struct console console;
83 struct tty_driver *tty_driver;
84 struct tty_struct *tty;
85 int tty_open_count;
86 struct fiq_debugger_ringbuf *tty_rbuf;
87#endif
Iliyan Malchevc1db50b2010-06-05 17:36:24 -070088
89 unsigned int last_irqs[NR_IRQS];
Rebecca Schultz Zavinb824eef2010-10-22 15:55:17 -070090 unsigned int last_local_timer_irqs[NR_CPUS];
Iliyan Malchevc1db50b2010-06-05 17:36:24 -070091};
92
93#ifdef CONFIG_FIQ_DEBUGGER_NO_SLEEP
94static bool initial_no_sleep = true;
95#else
96static bool initial_no_sleep;
97#endif
98static bool initial_debug_enable;
Colin Cross4df8d7b2010-08-16 14:51:51 -070099static bool initial_console_enable;
Iliyan Malchevc1db50b2010-06-05 17:36:24 -0700100
101module_param_named(no_sleep, initial_no_sleep, bool, 0644);
102module_param_named(debug_enable, initial_debug_enable, bool, 0644);
Colin Cross4df8d7b2010-08-16 14:51:51 -0700103module_param_named(console_enable, initial_console_enable, bool, 0644);
Iliyan Malchevc1db50b2010-06-05 17:36:24 -0700104
105#ifdef CONFIG_FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON
106static inline void enable_wakeup_irq(struct fiq_debugger_state *state) {}
107static inline void disable_wakeup_irq(struct fiq_debugger_state *state) {}
108#else
109static inline void enable_wakeup_irq(struct fiq_debugger_state *state)
110{
111 if (state->wakeup_irq < 0)
112 return;
113 enable_irq(state->wakeup_irq);
114 if (!state->wakeup_irq_no_set_wake)
115 enable_irq_wake(state->wakeup_irq);
116}
117static inline void disable_wakeup_irq(struct fiq_debugger_state *state)
118{
119 if (state->wakeup_irq < 0)
120 return;
121 disable_irq_nosync(state->wakeup_irq);
122 if (!state->wakeup_irq_no_set_wake)
123 disable_irq_wake(state->wakeup_irq);
124}
125#endif
126
127static void debug_force_irq(struct fiq_debugger_state *state)
128{
129 unsigned int irq = state->signal_irq;
130 if (state->pdata->force_irq)
131 state->pdata->force_irq(state->pdev, irq);
132 else {
133 struct irq_chip *chip = get_irq_chip(irq);
134 if (chip && chip->retrigger)
135 chip->retrigger(irq);
136 }
137}
138
139static void debug_uart_flush(struct fiq_debugger_state *state)
140{
141 if (state->pdata->uart_flush)
142 state->pdata->uart_flush(state->pdev);
143}
144
145static void debug_puts(struct fiq_debugger_state *state, char *s)
146{
147 unsigned c;
148 while ((c = *s++)) {
149 if (c == '\n')
150 state->pdata->uart_putc(state->pdev, '\r');
151 state->pdata->uart_putc(state->pdev, c);
152 }
153}
154
155static void debug_prompt(struct fiq_debugger_state *state)
156{
157 debug_puts(state, "debug> ");
158}
159
160int log_buf_copy(char *dest, int idx, int len);
161static void dump_kernel_log(struct fiq_debugger_state *state)
162{
163 char buf[1024];
164 int idx = 0;
165 int ret;
166 int saved_oip;
167
168 /* setting oops_in_progress prevents log_buf_copy()
169 * from trying to take a spinlock which will make it
170 * very unhappy in some cases...
171 */
172 saved_oip = oops_in_progress;
173 oops_in_progress = 1;
174 for (;;) {
175 ret = log_buf_copy(buf, idx, 1023);
176 if (ret <= 0)
177 break;
178 buf[ret] = 0;
179 debug_puts(state, buf);
180 idx += ret;
181 }
182 oops_in_progress = saved_oip;
183}
184
185static char *mode_name(unsigned cpsr)
186{
187 switch (cpsr & MODE_MASK) {
188 case USR_MODE: return "USR";
189 case FIQ_MODE: return "FIQ";
190 case IRQ_MODE: return "IRQ";
191 case SVC_MODE: return "SVC";
192 case ABT_MODE: return "ABT";
193 case UND_MODE: return "UND";
194 case SYSTEM_MODE: return "SYS";
195 default: return "???";
196 }
197}
198
199static int debug_printf(void *cookie, const char *fmt, ...)
200{
201 struct fiq_debugger_state *state = cookie;
202 char buf[256];
203 va_list ap;
204
205 va_start(ap, fmt);
206 vsnprintf(buf, sizeof(buf), fmt, ap);
207 va_end(ap);
208
209 debug_puts(state, buf);
210 return state->debug_abort;
211}
212
213/* Safe outside fiq context */
214static int debug_printf_nfiq(void *cookie, const char *fmt, ...)
215{
216 struct fiq_debugger_state *state = cookie;
217 char buf[256];
218 va_list ap;
219 unsigned long irq_flags;
220
221 va_start(ap, fmt);
222 vsnprintf(buf, 128, fmt, ap);
223 va_end(ap);
224
225 local_irq_save(irq_flags);
226 debug_puts(state, buf);
227 debug_uart_flush(state);
228 local_irq_restore(irq_flags);
229 return state->debug_abort;
230}
231
232static void dump_regs(struct fiq_debugger_state *state, unsigned *regs)
233{
234 debug_printf(state, " r0 %08x r1 %08x r2 %08x r3 %08x\n",
235 regs[0], regs[1], regs[2], regs[3]);
236 debug_printf(state, " r4 %08x r5 %08x r6 %08x r7 %08x\n",
237 regs[4], regs[5], regs[6], regs[7]);
238 debug_printf(state, " r8 %08x r9 %08x r10 %08x r11 %08x mode %s\n",
239 regs[8], regs[9], regs[10], regs[11],
240 mode_name(regs[16]));
241 if ((regs[16] & MODE_MASK) == USR_MODE)
242 debug_printf(state, " ip %08x sp %08x lr %08x pc %08x "
243 "cpsr %08x\n", regs[12], regs[13], regs[14],
244 regs[15], regs[16]);
245 else
246 debug_printf(state, " ip %08x sp %08x lr %08x pc %08x "
247 "cpsr %08x spsr %08x\n", regs[12], regs[13],
248 regs[14], regs[15], regs[16], regs[17]);
249}
250
251struct mode_regs {
252 unsigned long sp_svc;
253 unsigned long lr_svc;
254 unsigned long spsr_svc;
255
256 unsigned long sp_abt;
257 unsigned long lr_abt;
258 unsigned long spsr_abt;
259
260 unsigned long sp_und;
261 unsigned long lr_und;
262 unsigned long spsr_und;
263
264 unsigned long sp_irq;
265 unsigned long lr_irq;
266 unsigned long spsr_irq;
267
268 unsigned long r8_fiq;
269 unsigned long r9_fiq;
270 unsigned long r10_fiq;
271 unsigned long r11_fiq;
272 unsigned long r12_fiq;
273 unsigned long sp_fiq;
274 unsigned long lr_fiq;
275 unsigned long spsr_fiq;
276};
277
278void __naked get_mode_regs(struct mode_regs *regs)
279{
280 asm volatile (
281 "mrs r1, cpsr\n"
282 "msr cpsr_c, #0xd3 @(SVC_MODE | PSR_I_BIT | PSR_F_BIT)\n"
283 "stmia r0!, {r13 - r14}\n"
284 "mrs r2, spsr\n"
285 "msr cpsr_c, #0xd7 @(ABT_MODE | PSR_I_BIT | PSR_F_BIT)\n"
286 "stmia r0!, {r2, r13 - r14}\n"
287 "mrs r2, spsr\n"
288 "msr cpsr_c, #0xdb @(UND_MODE | PSR_I_BIT | PSR_F_BIT)\n"
289 "stmia r0!, {r2, r13 - r14}\n"
290 "mrs r2, spsr\n"
291 "msr cpsr_c, #0xd2 @(IRQ_MODE | PSR_I_BIT | PSR_F_BIT)\n"
292 "stmia r0!, {r2, r13 - r14}\n"
293 "mrs r2, spsr\n"
294 "msr cpsr_c, #0xd1 @(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)\n"
295 "stmia r0!, {r2, r8 - r14}\n"
296 "mrs r2, spsr\n"
297 "stmia r0!, {r2}\n"
298 "msr cpsr_c, r1\n"
299 "bx lr\n");
300}
301
302
303static void dump_allregs(struct fiq_debugger_state *state, unsigned *regs)
304{
305 struct mode_regs mode_regs;
306 dump_regs(state, regs);
307 get_mode_regs(&mode_regs);
308 debug_printf(state, " svc: sp %08x lr %08x spsr %08x\n",
309 mode_regs.sp_svc, mode_regs.lr_svc, mode_regs.spsr_svc);
310 debug_printf(state, " abt: sp %08x lr %08x spsr %08x\n",
311 mode_regs.sp_abt, mode_regs.lr_abt, mode_regs.spsr_abt);
312 debug_printf(state, " und: sp %08x lr %08x spsr %08x\n",
313 mode_regs.sp_und, mode_regs.lr_und, mode_regs.spsr_und);
314 debug_printf(state, " irq: sp %08x lr %08x spsr %08x\n",
315 mode_regs.sp_irq, mode_regs.lr_irq, mode_regs.spsr_irq);
316 debug_printf(state, " fiq: r8 %08x r9 %08x r10 %08x r11 %08x "
317 "r12 %08x\n",
318 mode_regs.r8_fiq, mode_regs.r9_fiq, mode_regs.r10_fiq,
319 mode_regs.r11_fiq, mode_regs.r12_fiq);
320 debug_printf(state, " fiq: sp %08x lr %08x spsr %08x\n",
321 mode_regs.sp_fiq, mode_regs.lr_fiq, mode_regs.spsr_fiq);
322}
323
324static void dump_irqs(struct fiq_debugger_state *state)
325{
326 int n;
Rebecca Schultz Zavinb824eef2010-10-22 15:55:17 -0700327 unsigned int cpu;
328
Iliyan Malchevc1db50b2010-06-05 17:36:24 -0700329 debug_printf(state, "irqnr total since-last status name\n");
330 for (n = 0; n < NR_IRQS; n++) {
331 struct irqaction *act = irq_desc[n].action;
332 if (!act && !kstat_irqs(n))
333 continue;
334 debug_printf(state, "%5d: %10u %11u %8x %s\n", n,
335 kstat_irqs(n),
336 kstat_irqs(n) - state->last_irqs[n],
337 irq_desc[n].status,
338 (act && act->name) ? act->name : "???");
339 state->last_irqs[n] = kstat_irqs(n);
340 }
Rebecca Schultz Zavinb824eef2010-10-22 15:55:17 -0700341
342 for (cpu = 0; cpu < NR_CPUS; cpu++) {
343
344 debug_printf(state, "LOC %d: %10u %11u\n", cpu,
345 __IRQ_STAT(cpu, local_timer_irqs),
346 __IRQ_STAT(cpu, local_timer_irqs) -
347 state->last_local_timer_irqs[cpu]);
348 state->last_local_timer_irqs[cpu] =
349 __IRQ_STAT(cpu, local_timer_irqs);
350 }
Iliyan Malchevc1db50b2010-06-05 17:36:24 -0700351}
352
353struct stacktrace_state {
354 struct fiq_debugger_state *state;
355 unsigned int depth;
356};
357
358static int report_trace(struct stackframe *frame, void *d)
359{
360 struct stacktrace_state *sts = d;
361
362 if (sts->depth) {
363 debug_printf(sts->state,
364 " pc: %p (%pF), lr %p (%pF), sp %p, fp %p\n",
365 frame->pc, frame->pc, frame->lr, frame->lr,
366 frame->sp, frame->fp);
367 sts->depth--;
368 return 0;
369 }
370 debug_printf(sts->state, " ...\n");
371
372 return sts->depth == 0;
373}
374
375struct frame_tail {
376 struct frame_tail *fp;
377 unsigned long sp;
378 unsigned long lr;
379} __attribute__((packed));
380
381static struct frame_tail *user_backtrace(struct fiq_debugger_state *state,
382 struct frame_tail *tail)
383{
384 struct frame_tail buftail[2];
385
386 /* Also check accessibility of one struct frame_tail beyond */
387 if (!access_ok(VERIFY_READ, tail, sizeof(buftail))) {
388 debug_printf(state, " invalid frame pointer %p\n", tail);
389 return NULL;
390 }
391 if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail))) {
392 debug_printf(state,
393 " failed to copy frame pointer %p\n", tail);
394 return NULL;
395 }
396
397 debug_printf(state, " %p\n", buftail[0].lr);
398
399 /* frame pointers should strictly progress back up the stack
400 * (towards higher addresses) */
401 if (tail >= buftail[0].fp)
402 return NULL;
403
404 return buftail[0].fp-1;
405}
406
407void dump_stacktrace(struct fiq_debugger_state *state,
408 struct pt_regs * const regs, unsigned int depth, void *ssp)
409{
410 struct frame_tail *tail;
Colin Cross24b3bd42010-10-01 23:41:38 -0700411 struct thread_info *real_thread_info = THREAD_INFO(ssp);
Iliyan Malchevc1db50b2010-06-05 17:36:24 -0700412 struct stacktrace_state sts;
413
414 sts.depth = depth;
415 sts.state = state;
416 *current_thread_info() = *real_thread_info;
417
418 if (!current)
419 debug_printf(state, "current NULL\n");
420 else
421 debug_printf(state, "pid: %d comm: %s\n",
422 current->pid, current->comm);
423 dump_regs(state, (unsigned *)regs);
424
425 if (!user_mode(regs)) {
426 struct stackframe frame;
427 frame.fp = regs->ARM_fp;
428 frame.sp = regs->ARM_sp;
429 frame.lr = regs->ARM_lr;
430 frame.pc = regs->ARM_pc;
431 debug_printf(state,
432 " pc: %p (%pF), lr %p (%pF), sp %p, fp %p\n",
433 regs->ARM_pc, regs->ARM_pc, regs->ARM_lr, regs->ARM_lr,
434 regs->ARM_sp, regs->ARM_fp);
435 walk_stackframe(&frame, report_trace, &sts);
436 return;
437 }
438
439 tail = ((struct frame_tail *) regs->ARM_fp) - 1;
440 while (depth-- && tail && !((unsigned long) tail & 3))
441 tail = user_backtrace(state, tail);
442}
443
444static void debug_exec(struct fiq_debugger_state *state,
445 const char *cmd, unsigned *regs, void *svc_sp)
446{
447 if (!strcmp(cmd, "pc")) {
448 debug_printf(state, " pc %08x cpsr %08x mode %s\n",
449 regs[15], regs[16], mode_name(regs[16]));
450 } else if (!strcmp(cmd, "regs")) {
451 dump_regs(state, regs);
452 } else if (!strcmp(cmd, "allregs")) {
453 dump_allregs(state, regs);
454 } else if (!strcmp(cmd, "bt")) {
455 dump_stacktrace(state, (struct pt_regs *)regs, 100, svc_sp);
456 } else if (!strcmp(cmd, "reboot")) {
457 arch_reset(0, 0);
458 } else if (!strcmp(cmd, "irqs")) {
459 dump_irqs(state);
460 } else if (!strcmp(cmd, "kmsg")) {
461 dump_kernel_log(state);
462 } else if (!strcmp(cmd, "version")) {
463 debug_printf(state, "%s\n", linux_banner);
464 } else if (!strcmp(cmd, "sleep")) {
465 state->no_sleep = false;
466 } else if (!strcmp(cmd, "nosleep")) {
467 state->no_sleep = true;
Colin Cross4df8d7b2010-08-16 14:51:51 -0700468 } else if (!strcmp(cmd, "console")) {
469 state->console_enable = true;
470 debug_printf(state, "console mode\n");
Colin Cross24b3bd42010-10-01 23:41:38 -0700471 } else if (!strcmp(cmd, "cpu")) {
472 debug_printf(state, "cpu %d\n", state->current_cpu);
473 } else if (!strncmp(cmd, "cpu ", 4)) {
474 unsigned long cpu = 0;
475 if (strict_strtoul(cmd + 4, 10, &cpu) == 0)
476 state->current_cpu = cpu;
477 else
478 debug_printf(state, "invalid cpu\n");
479 debug_printf(state, "cpu %d\n", state->current_cpu);
Iliyan Malchevc1db50b2010-06-05 17:36:24 -0700480 } else {
481 if (state->debug_busy) {
482 debug_printf(state,
483 "command processor busy. trying to abort.\n");
484 state->debug_abort = -1;
485 } else {
486 strcpy(state->debug_cmd, cmd);
487 state->debug_busy = 1;
488 }
489
490 debug_force_irq(state);
491
492 return;
493 }
Colin Cross4df8d7b2010-08-16 14:51:51 -0700494 if (!state->console_enable)
495 debug_prompt(state);
Iliyan Malchevc1db50b2010-06-05 17:36:24 -0700496}
497
498static void sleep_timer_expired(unsigned long data)
499{
500 struct fiq_debugger_state *state = (struct fiq_debugger_state *)data;
501
502 if (state->uart_clk_enabled && !state->no_sleep) {
503 if (state->debug_enable) {
504 state->debug_enable = false;
505 debug_printf_nfiq(state, "suspending fiq debugger\n");
506 }
507 state->ignore_next_wakeup_irq = true;
508 if (state->clk)
509 clk_disable(state->clk);
510 state->uart_clk_enabled = false;
511 enable_wakeup_irq(state);
512 }
513 wake_unlock(&state->debugger_wake_lock);
514}
515
516static irqreturn_t wakeup_irq_handler(int irq, void *dev)
517{
518 struct fiq_debugger_state *state = dev;
519
520 if (!state->no_sleep)
521 debug_puts(state, "WAKEUP\n");
522 if (state->ignore_next_wakeup_irq)
523 state->ignore_next_wakeup_irq = false;
524 else if (!state->uart_clk_enabled) {
525 wake_lock(&state->debugger_wake_lock);
526 if (state->clk)
527 clk_enable(state->clk);
528 state->uart_clk_enabled = true;
529 disable_wakeup_irq(state);
530 mod_timer(&state->sleep_timer, jiffies + HZ / 2);
531 }
532 return IRQ_HANDLED;
533}
534
535static irqreturn_t debug_irq(int irq, void *dev)
536{
537 struct fiq_debugger_state *state = dev;
538 if (state->pdata->force_irq_ack)
539 state->pdata->force_irq_ack(state->pdev, state->signal_irq);
540
541 if (!state->no_sleep) {
542 wake_lock(&state->debugger_wake_lock);
543 mod_timer(&state->sleep_timer, jiffies + HZ * 5);
544 }
Colin Cross4df8d7b2010-08-16 14:51:51 -0700545#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE)
546 if (state->tty) {
547 int i;
548 int count = fiq_debugger_ringbuf_level(state->tty_rbuf);
549 for (i = 0; i < count; i++) {
550 int c = fiq_debugger_ringbuf_peek(state->tty_rbuf, i);
551 tty_insert_flip_char(state->tty, c, TTY_NORMAL);
552 if (!fiq_debugger_ringbuf_consume(state->tty_rbuf, 1))
553 pr_warn("fiq tty failed to consume byte\n");
554 }
555 tty_flip_buffer_push(state->tty);
556 }
557#endif
Iliyan Malchevc1db50b2010-06-05 17:36:24 -0700558 if (state->debug_busy) {
559 struct kdbg_ctxt ctxt;
560
561 ctxt.printf = debug_printf_nfiq;
562 ctxt.cookie = state;
563 kernel_debugger(&ctxt, state->debug_cmd);
564 debug_prompt(state);
565
566 state->debug_busy = 0;
567 }
568 return IRQ_HANDLED;
569}
570
571static int debug_getc(struct fiq_debugger_state *state)
572{
573 return state->pdata->uart_getc(state->pdev);
574}
575
576static void debug_fiq(struct fiq_glue_handler *h, void *regs, void *svc_sp)
577{
578 struct fiq_debugger_state *state =
579 container_of(h, struct fiq_debugger_state, handler);
580 int c;
581 static int last_c;
582 int count = 0;
Colin Cross24b3bd42010-10-01 23:41:38 -0700583 unsigned int this_cpu = THREAD_INFO(svc_sp)->cpu;
584
585 if (this_cpu != state->current_cpu) {
586 if (state->in_fiq)
587 return;
588
589 if (atomic_inc_return(&state->unhandled_fiq_count) !=
590 MAX_UNHANDLED_FIQ_COUNT)
591 return;
592
593 debug_printf(state, "fiq_debugger: cpu %d not responding, "
594 "reverting to cpu %d\n", state->current_cpu,
595 this_cpu);
596
597 atomic_set(&state->unhandled_fiq_count, 0);
598 state->current_cpu = this_cpu;
599 return;
600 }
601
602 state->in_fiq = true;
Iliyan Malchevc1db50b2010-06-05 17:36:24 -0700603
604 while ((c = debug_getc(state)) != FIQ_DEBUGGER_NO_CHAR) {
605 count++;
606 if (!state->debug_enable) {
607 if ((c == 13) || (c == 10)) {
608 state->debug_enable = true;
609 state->debug_count = 0;
610 debug_prompt(state);
611 }
Colin Cross4df8d7b2010-08-16 14:51:51 -0700612 } else if (c == FIQ_DEBUGGER_BREAK) {
613 state->console_enable = false;
614 debug_puts(state, "fiq debugger mode\n");
615 state->debug_count = 0;
616 debug_prompt(state);
617#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE
618 } else if (state->console_enable && state->tty_rbuf) {
619 fiq_debugger_ringbuf_push(state->tty_rbuf, c);
620 debug_force_irq(state);
621#endif
Iliyan Malchevc1db50b2010-06-05 17:36:24 -0700622 } else if ((c >= ' ') && (c < 127)) {
623 if (state->debug_count < (DEBUG_MAX - 1)) {
624 state->debug_buf[state->debug_count++] = c;
625 state->pdata->uart_putc(state->pdev, c);
626 }
627 } else if ((c == 8) || (c == 127)) {
628 if (state->debug_count > 0) {
629 state->debug_count--;
630 state->pdata->uart_putc(state->pdev, 8);
631 state->pdata->uart_putc(state->pdev, ' ');
632 state->pdata->uart_putc(state->pdev, 8);
633 }
634 } else if ((c == 13) || (c == 10)) {
635 if (c == '\r' || (c == '\n' && last_c != '\r')) {
636 state->pdata->uart_putc(state->pdev, '\r');
637 state->pdata->uart_putc(state->pdev, '\n');
638 }
639 if (state->debug_count) {
640 state->debug_buf[state->debug_count] = 0;
641 state->debug_count = 0;
642 debug_exec(state, state->debug_buf,
643 regs, svc_sp);
644 } else {
645 debug_prompt(state);
646 }
647 }
648 last_c = c;
649 }
650 debug_uart_flush(state);
651 if (state->pdata->fiq_ack)
652 state->pdata->fiq_ack(state->pdev, state->fiq);
653
654 /* poke sleep timer if necessary */
655 if (state->debug_enable && !state->no_sleep)
656 debug_force_irq(state);
Colin Cross24b3bd42010-10-01 23:41:38 -0700657
658 atomic_set(&state->unhandled_fiq_count, 0);
659 state->in_fiq = false;
Iliyan Malchevc1db50b2010-06-05 17:36:24 -0700660}
661
662static void debug_resume(struct fiq_glue_handler *h)
663{
664 struct fiq_debugger_state *state =
665 container_of(h, struct fiq_debugger_state, handler);
666 if (state->pdata->uart_resume)
667 state->pdata->uart_resume(state->pdev);
668}
669
Colin Cross4df8d7b2010-08-16 14:51:51 -0700670#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE)
671struct tty_driver *debug_console_device(struct console *co, int *index)
672{
673 struct fiq_debugger_state *state;
674 state = container_of(co, struct fiq_debugger_state, console);
675 *index = 0;
676 return state->tty_driver;
677}
678
679static void debug_console_write(struct console *co,
680 const char *s, unsigned int count)
681{
682 struct fiq_debugger_state *state;
683
684 state = container_of(co, struct fiq_debugger_state, console);
685
686 if (!state->console_enable)
687 return;
688
689 while (count--) {
690 if (*s == '\n')
691 state->pdata->uart_putc(state->pdev, '\r');
692 state->pdata->uart_putc(state->pdev, *s++);
693 }
694 debug_uart_flush(state);
695}
696
697static struct console fiq_debugger_console = {
698 .name = "ttyFIQ",
699 .device = debug_console_device,
700 .write = debug_console_write,
701 .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_ENABLED,
702};
703
704int fiq_tty_open(struct tty_struct *tty, struct file *filp)
705{
706 struct fiq_debugger_state *state = tty->driver->driver_state;
707 if (state->tty_open_count++)
708 return 0;
709
710 tty->driver_data = state;
711 state->tty = tty;
712 return 0;
713}
714
715void fiq_tty_close(struct tty_struct *tty, struct file *filp)
716{
717 struct fiq_debugger_state *state = tty->driver_data;
718 if (--state->tty_open_count)
719 return;
720 state->tty = NULL;
721}
722
723int fiq_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
724{
725 int i;
726 struct fiq_debugger_state *state = tty->driver_data;
727
728 if (!state->console_enable)
729 return count;
730
731 if (state->clk)
732 clk_enable(state->clk);
733 for (i = 0; i < count; i++)
734 state->pdata->uart_putc(state->pdev, *buf++);
735 if (state->clk)
736 clk_disable(state->clk);
737
738 return count;
739}
740
741int fiq_tty_write_room(struct tty_struct *tty)
742{
743 return 1024;
744}
745
746static const struct tty_operations fiq_tty_driver_ops = {
747 .write = fiq_tty_write,
748 .write_room = fiq_tty_write_room,
749 .open = fiq_tty_open,
750 .close = fiq_tty_close,
751};
752
753static int fiq_debugger_tty_init(struct fiq_debugger_state *state)
754{
755 int ret = -EINVAL;
756
757 state->tty_driver = alloc_tty_driver(1);
758 if (!state->tty_driver) {
759 pr_err("Failed to allocate fiq debugger tty\n");
760 return -ENOMEM;
761 }
762
763 state->tty_driver->owner = THIS_MODULE;
764 state->tty_driver->driver_name = "fiq-debugger";
765 state->tty_driver->name = "ttyFIQ";
766 state->tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
767 state->tty_driver->subtype = SERIAL_TYPE_NORMAL;
768 state->tty_driver->init_termios = tty_std_termios;
769 state->tty_driver->init_termios.c_cflag =
770 B115200 | CS8 | CREAD | HUPCL | CLOCAL;
771 state->tty_driver->init_termios.c_ispeed =
772 state->tty_driver->init_termios.c_ospeed = 115200;
773 state->tty_driver->flags = TTY_DRIVER_REAL_RAW;
774 tty_set_operations(state->tty_driver, &fiq_tty_driver_ops);
775 state->tty_driver->driver_state = state;
776
777 ret = tty_register_driver(state->tty_driver);
778 if (ret) {
779 pr_err("Failed to register fiq tty: %d\n", ret);
780 goto err;
781 }
782
783 state->tty_rbuf = fiq_debugger_ringbuf_alloc(1024);
784 if (!state->tty_rbuf) {
785 pr_err("Failed to allocate fiq debugger ringbuf\n");
786 ret = -ENOMEM;
787 goto err;
788 }
789
790 pr_info("Registered FIQ tty driver %p\n", state->tty_driver);
791 return 0;
792
793err:
794 fiq_debugger_ringbuf_free(state->tty_rbuf);
795 state->tty_rbuf = NULL;
796 put_tty_driver(state->tty_driver);
797 return ret;
798}
799#endif
800
Iliyan Malchevc1db50b2010-06-05 17:36:24 -0700801static int fiq_debugger_probe(struct platform_device *pdev)
802{
803 int ret;
804 struct fiq_debugger_pdata *pdata = dev_get_platdata(&pdev->dev);
805 struct fiq_debugger_state *state;
806
807 if (!pdata->uart_getc || !pdata->uart_putc || !pdata->fiq_enable)
808 return -EINVAL;
809
810 state = kzalloc(sizeof(*state), GFP_KERNEL);
811 state->handler.fiq = debug_fiq;
812 state->handler.resume = debug_resume;
813 setup_timer(&state->sleep_timer, sleep_timer_expired,
814 (unsigned long)state);
815 state->pdata = pdata;
816 state->pdev = pdev;
817 state->no_sleep = initial_no_sleep;
818 state->debug_enable = initial_debug_enable;
Colin Cross4df8d7b2010-08-16 14:51:51 -0700819 state->console_enable = initial_console_enable;
Iliyan Malchevc1db50b2010-06-05 17:36:24 -0700820
821 state->fiq = platform_get_irq_byname(pdev, "fiq");
822 state->signal_irq = platform_get_irq_byname(pdev, "signal");
823 state->wakeup_irq = platform_get_irq_byname(pdev, "wakeup");
824
825 if (state->wakeup_irq < 0)
826 state->no_sleep = true;
827 state->ignore_next_wakeup_irq = !state->no_sleep;
828
829 wake_lock_init(&state->debugger_wake_lock,
830 WAKE_LOCK_SUSPEND, "serial-debug");
831
832 state->clk = clk_get(&pdev->dev, NULL);
833 if (IS_ERR(state->clk))
834 state->clk = NULL;
835
836 if (state->clk)
837 clk_enable(state->clk);
838
839 if (pdata->uart_init) {
840 ret = pdata->uart_init(pdev);
841 if (ret)
842 goto err_uart_init;
843 }
844
845 debug_printf_nfiq(state, "<hit enter %sto activate fiq debugger>\n",
846 state->no_sleep ? "" : "twice ");
847
848 ret = fiq_glue_register_handler(&state->handler);
849 if (ret) {
850 pr_err("serial_debugger: could not install fiq handler\n");
851 goto err_register_fiq;
852 }
853
854 pdata->fiq_enable(pdev, state->fiq, 1);
855
856 if (state->clk)
857 clk_disable(state->clk);
858
859 ret = request_irq(state->signal_irq, debug_irq,
860 IRQF_TRIGGER_RISING, "debug", state);
861 if (ret)
862 pr_err("serial_debugger: could not install signal_irq");
863
864 if (state->wakeup_irq >= 0) {
865 ret = request_irq(state->wakeup_irq, wakeup_irq_handler,
866 IRQF_TRIGGER_FALLING | IRQF_DISABLED,
867 "debug-wakeup", state);
868 if (ret) {
869 pr_err("serial_debugger: "
870 "could not install wakeup irq\n");
871 state->wakeup_irq = -1;
872 } else {
873 ret = enable_irq_wake(state->wakeup_irq);
874 if (ret) {
875 pr_err("serial_debugger: "
876 "could not enable wakeup\n");
877 state->wakeup_irq_no_set_wake = true;
878 }
879 }
880 }
881 if (state->no_sleep)
882 wakeup_irq_handler(state->wakeup_irq, state);
883
Colin Cross4df8d7b2010-08-16 14:51:51 -0700884#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE)
885 state->console = fiq_debugger_console;
886 register_console(&state->console);
887 fiq_debugger_tty_init(state);
888#endif
Iliyan Malchevc1db50b2010-06-05 17:36:24 -0700889 return 0;
890
891err_register_fiq:
892 if (pdata->uart_free)
893 pdata->uart_free(pdev);
894err_uart_init:
895 kfree(state);
896 if (state->clk)
897 clk_put(state->clk);
898 return ret;
899}
900
901static struct platform_driver fiq_debugger_driver = {
902 .probe = fiq_debugger_probe,
903 .driver.name = "fiq_debugger",
904};
905
906static int __init fiq_debugger_init(void)
907{
908 return platform_driver_register(&fiq_debugger_driver);
909}
910
911postcore_initcall(fiq_debugger_init);