aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/kgdb.c
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2010-02-22 07:48:51 -0500
committerJens Axboe <jens.axboe@oracle.com>2010-02-22 07:48:51 -0500
commitf11cbd74c5ff3614f6390b4de67a6ffdc614c378 (patch)
tree6a30920ade9eeaac5bf6d6263b5d09712e882eb0 /arch/blackfin/kernel/kgdb.c
parent429c42c9d246f5bda868495c09974312a0177328 (diff)
parentaea187c46f7d03ce985e55eb1398d0776a15b928 (diff)
Merge branch 'master' into for-2.6.34
Diffstat (limited to 'arch/blackfin/kernel/kgdb.c')
-rw-r--r--arch/blackfin/kernel/kgdb.c207
1 files changed, 1 insertions, 206 deletions
diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c
index f1036b6b9293..34c7c3ed2c9c 100644
--- a/arch/blackfin/kernel/kgdb.c
+++ b/arch/blackfin/kernel/kgdb.c
@@ -6,23 +6,9 @@
6 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
7 */ 7 */
8 8
9#include <linux/string.h>
10#include <linux/kernel.h>
11#include <linux/sched.h>
12#include <linux/smp.h>
13#include <linux/spinlock.h>
14#include <linux/delay.h>
15#include <linux/ptrace.h> /* for linux pt_regs struct */ 9#include <linux/ptrace.h> /* for linux pt_regs struct */
16#include <linux/kgdb.h> 10#include <linux/kgdb.h>
17#include <linux/console.h>
18#include <linux/init.h>
19#include <linux/errno.h>
20#include <linux/irq.h>
21#include <linux/uaccess.h> 11#include <linux/uaccess.h>
22#include <asm/system.h>
23#include <asm/traps.h>
24#include <asm/blackfin.h>
25#include <asm/dma.h>
26 12
27void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) 13void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
28{ 14{
@@ -147,7 +133,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
147 regs->lb1 = gdb_regs[BFIN_LB1]; 133 regs->lb1 = gdb_regs[BFIN_LB1];
148 regs->usp = gdb_regs[BFIN_USP]; 134 regs->usp = gdb_regs[BFIN_USP];
149 regs->syscfg = gdb_regs[BFIN_SYSCFG]; 135 regs->syscfg = gdb_regs[BFIN_SYSCFG];
150 regs->retx = gdb_regs[BFIN_PC]; 136 regs->retx = gdb_regs[BFIN_RETX];
151 regs->retn = gdb_regs[BFIN_RETN]; 137 regs->retn = gdb_regs[BFIN_RETN];
152 regs->rete = gdb_regs[BFIN_RETE]; 138 regs->rete = gdb_regs[BFIN_RETE];
153 regs->pc = gdb_regs[BFIN_PC]; 139 regs->pc = gdb_regs[BFIN_PC];
@@ -424,182 +410,6 @@ struct kgdb_arch arch_kgdb_ops = {
424 .correct_hw_break = bfin_correct_hw_break, 410 .correct_hw_break = bfin_correct_hw_break,
425}; 411};
426 412
427static int hex(char ch)
428{
429 if ((ch >= 'a') && (ch <= 'f'))
430 return ch - 'a' + 10;
431 if ((ch >= '0') && (ch <= '9'))
432 return ch - '0';
433 if ((ch >= 'A') && (ch <= 'F'))
434 return ch - 'A' + 10;
435 return -1;
436}
437
438static int validate_memory_access_address(unsigned long addr, int size)
439{
440 if (size < 0 || addr == 0)
441 return -EFAULT;
442 return bfin_mem_access_type(addr, size);
443}
444
445static int bfin_probe_kernel_read(char *dst, char *src, int size)
446{
447 unsigned long lsrc = (unsigned long)src;
448 int mem_type;
449
450 mem_type = validate_memory_access_address(lsrc, size);
451 if (mem_type < 0)
452 return mem_type;
453
454 if (lsrc >= SYSMMR_BASE) {
455 if (size == 2 && lsrc % 2 == 0) {
456 u16 mmr = bfin_read16(src);
457 memcpy(dst, &mmr, sizeof(mmr));
458 return 0;
459 } else if (size == 4 && lsrc % 4 == 0) {
460 u32 mmr = bfin_read32(src);
461 memcpy(dst, &mmr, sizeof(mmr));
462 return 0;
463 }
464 } else {
465 switch (mem_type) {
466 case BFIN_MEM_ACCESS_CORE:
467 case BFIN_MEM_ACCESS_CORE_ONLY:
468 return probe_kernel_read(dst, src, size);
469 /* XXX: should support IDMA here with SMP */
470 case BFIN_MEM_ACCESS_DMA:
471 if (dma_memcpy(dst, src, size))
472 return 0;
473 break;
474 case BFIN_MEM_ACCESS_ITEST:
475 if (isram_memcpy(dst, src, size))
476 return 0;
477 break;
478 }
479 }
480
481 return -EFAULT;
482}
483
484static int bfin_probe_kernel_write(char *dst, char *src, int size)
485{
486 unsigned long ldst = (unsigned long)dst;
487 int mem_type;
488
489 mem_type = validate_memory_access_address(ldst, size);
490 if (mem_type < 0)
491 return mem_type;
492
493 if (ldst >= SYSMMR_BASE) {
494 if (size == 2 && ldst % 2 == 0) {
495 u16 mmr;
496 memcpy(&mmr, src, sizeof(mmr));
497 bfin_write16(dst, mmr);
498 return 0;
499 } else if (size == 4 && ldst % 4 == 0) {
500 u32 mmr;
501 memcpy(&mmr, src, sizeof(mmr));
502 bfin_write32(dst, mmr);
503 return 0;
504 }
505 } else {
506 switch (mem_type) {
507 case BFIN_MEM_ACCESS_CORE:
508 case BFIN_MEM_ACCESS_CORE_ONLY:
509 return probe_kernel_write(dst, src, size);
510 /* XXX: should support IDMA here with SMP */
511 case BFIN_MEM_ACCESS_DMA:
512 if (dma_memcpy(dst, src, size))
513 return 0;
514 break;
515 case BFIN_MEM_ACCESS_ITEST:
516 if (isram_memcpy(dst, src, size))
517 return 0;
518 break;
519 }
520 }
521
522 return -EFAULT;
523}
524
525/*
526 * Convert the memory pointed to by mem into hex, placing result in buf.
527 * Return a pointer to the last char put in buf (null). May return an error.
528 */
529int kgdb_mem2hex(char *mem, char *buf, int count)
530{
531 char *tmp;
532 int err;
533
534 /*
535 * We use the upper half of buf as an intermediate buffer for the
536 * raw memory copy. Hex conversion will work against this one.
537 */
538 tmp = buf + count;
539
540 err = bfin_probe_kernel_read(tmp, mem, count);
541 if (!err) {
542 while (count > 0) {
543 buf = pack_hex_byte(buf, *tmp);
544 tmp++;
545 count--;
546 }
547
548 *buf = 0;
549 }
550
551 return err;
552}
553
554/*
555 * Copy the binary array pointed to by buf into mem. Fix $, #, and
556 * 0x7d escaped with 0x7d. Return a pointer to the character after
557 * the last byte written.
558 */
559int kgdb_ebin2mem(char *buf, char *mem, int count)
560{
561 char *tmp_old, *tmp_new;
562 int size;
563
564 tmp_old = tmp_new = buf;
565
566 for (size = 0; size < count; ++size) {
567 if (*tmp_old == 0x7d)
568 *tmp_new = *(++tmp_old) ^ 0x20;
569 else
570 *tmp_new = *tmp_old;
571 tmp_new++;
572 tmp_old++;
573 }
574
575 return bfin_probe_kernel_write(mem, buf, count);
576}
577
578/*
579 * Convert the hex array pointed to by buf into binary to be placed in mem.
580 * Return a pointer to the character AFTER the last byte written.
581 * May return an error.
582 */
583int kgdb_hex2mem(char *buf, char *mem, int count)
584{
585 char *tmp_raw, *tmp_hex;
586
587 /*
588 * We use the upper half of buf as an intermediate buffer for the
589 * raw memory that is converted from hex.
590 */
591 tmp_raw = buf + count * 2;
592
593 tmp_hex = tmp_raw - 1;
594 while (tmp_hex >= buf) {
595 tmp_raw--;
596 *tmp_raw = hex(*tmp_hex--);
597 *tmp_raw |= hex(*tmp_hex--) << 4;
598 }
599
600 return bfin_probe_kernel_write(mem, tmp_raw, count);
601}
602
603#define IN_MEM(addr, size, l1_addr, l1_size) \ 413#define IN_MEM(addr, size, l1_addr, l1_size) \
604({ \ 414({ \
605 unsigned long __addr = (unsigned long)(addr); \ 415 unsigned long __addr = (unsigned long)(addr); \
@@ -629,21 +439,6 @@ int kgdb_validate_break_address(unsigned long addr)
629 return -EFAULT; 439 return -EFAULT;
630} 440}
631 441
632int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr)
633{
634 int err = bfin_probe_kernel_read(saved_instr, (char *)addr,
635 BREAK_INSTR_SIZE);
636 if (err)
637 return err;
638 return bfin_probe_kernel_write((char *)addr, arch_kgdb_ops.gdb_bpt_instr,
639 BREAK_INSTR_SIZE);
640}
641
642int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle)
643{
644 return bfin_probe_kernel_write((char *)addr, bundle, BREAK_INSTR_SIZE);
645}
646
647int kgdb_arch_init(void) 442int kgdb_arch_init(void)
648{ 443{
649 kgdb_single_step = 0; 444 kgdb_single_step = 0;