diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2010-02-22 07:48:51 -0500 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2010-02-22 07:48:51 -0500 |
commit | f11cbd74c5ff3614f6390b4de67a6ffdc614c378 (patch) | |
tree | 6a30920ade9eeaac5bf6d6263b5d09712e882eb0 /arch/blackfin/kernel/kgdb.c | |
parent | 429c42c9d246f5bda868495c09974312a0177328 (diff) | |
parent | aea187c46f7d03ce985e55eb1398d0776a15b928 (diff) |
Merge branch 'master' into for-2.6.34
Diffstat (limited to 'arch/blackfin/kernel/kgdb.c')
-rw-r--r-- | arch/blackfin/kernel/kgdb.c | 207 |
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 | ||
27 | void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) | 13 | void 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 | ||
427 | static 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 | |||
438 | static 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 | |||
445 | static 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 | |||
484 | static 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 | */ | ||
529 | int 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 | */ | ||
559 | int 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 | */ | ||
583 | int 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 | ||
632 | int 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 | |||
642 | int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle) | ||
643 | { | ||
644 | return bfin_probe_kernel_write((char *)addr, bundle, BREAK_INSTR_SIZE); | ||
645 | } | ||
646 | |||
647 | int kgdb_arch_init(void) | 442 | int kgdb_arch_init(void) |
648 | { | 443 | { |
649 | kgdb_single_step = 0; | 444 | kgdb_single_step = 0; |