ptrace_h8s.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * linux/arch/h8300/platform/h8s/ptrace_h8s.c
  3. * ptrace cpu depend helper functions
  4. *
  5. * Yoshinori Sato <ysato@users.sourceforge.jp>
  6. *
  7. * This file is subject to the terms and conditions of the GNU General
  8. * Public License. See the file COPYING in the main directory of
  9. * this archive for more details.
  10. */
  11. #include <linux/linkage.h>
  12. #include <linux/sched.h>
  13. #include <linux/errno.h>
  14. #include <asm/ptrace.h>
  15. #define CCR_MASK 0x6f
  16. #define EXR_TRACE 0x80
  17. /* Mapping from PT_xxx to the stack offset at which the register is
  18. saved. Notice that usp has no stack-slot and needs to be treated
  19. specially (see get_reg/put_reg below). */
  20. static const int h8300_register_offset[] = {
  21. PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4),
  22. PT_REG(er5), PT_REG(er6), PT_REG(er0), PT_REG(orig_er0),
  23. PT_REG(ccr), PT_REG(pc), 0, PT_REG(exr)
  24. };
  25. /* read register */
  26. long h8300_get_reg(struct task_struct *task, int regno)
  27. {
  28. switch (regno) {
  29. case PT_USP:
  30. return task->thread.usp + sizeof(long)*2 + 2;
  31. case PT_CCR:
  32. case PT_EXR:
  33. return *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]);
  34. default:
  35. return *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]);
  36. }
  37. }
  38. /* write register */
  39. int h8300_put_reg(struct task_struct *task, int regno, unsigned long data)
  40. {
  41. unsigned short oldccr;
  42. switch (regno) {
  43. case PT_USP:
  44. task->thread.usp = data - sizeof(long)*2 - 2;
  45. case PT_CCR:
  46. oldccr = *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]);
  47. oldccr &= ~CCR_MASK;
  48. data &= CCR_MASK;
  49. data |= oldccr;
  50. *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]) = data;
  51. break;
  52. case PT_EXR:
  53. /* exr modify not support */
  54. return -EIO;
  55. default:
  56. *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]) = data;
  57. break;
  58. }
  59. return 0;
  60. }
  61. /* disable singlestep */
  62. void user_disable_single_step(struct task_struct *child)
  63. {
  64. *(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) &= ~EXR_TRACE;
  65. }
  66. /* enable singlestep */
  67. void user_enable_single_step(struct task_struct *child)
  68. {
  69. *(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) |= EXR_TRACE;
  70. }
  71. asmlinkage void trace_trap(unsigned long bp)
  72. {
  73. (void)bp;
  74. force_sig(SIGTRAP,current);
  75. }