Hexagon: add support for single-stepping (v4+)
authorRichard Kuo <rkuo@codeaurora.org>
Thu, 7 Mar 2013 18:03:10 +0000 (12:03 -0600)
committerRichard Kuo <rkuo@codeaurora.org>
Wed, 1 May 2013 00:40:25 +0000 (19:40 -0500)
Hardware single-step is only available on v4 and later
architectures.

Signed-off-by: Richard Kuo <rkuo@codeaurora.org>
arch/hexagon/include/uapi/asm/ptrace.h
arch/hexagon/include/uapi/asm/registers.h
arch/hexagon/kernel/ptrace.c
arch/hexagon/kernel/traps.c
arch/hexagon/kernel/vm_entry.S
arch/hexagon/kernel/vm_vectors.S

index 1ffce0c6ee07559082fa475271e7656c2bbe3f9c..065e5b32313f1884b76365cba3e002d297ee3612 100644 (file)
@@ -36,4 +36,9 @@ extern const char *regs_query_register_name(unsigned int offset);
        ((struct pt_regs *) \
         ((unsigned long)current_thread_info() + THREAD_SIZE) - 1)
 
+#if CONFIG_HEXAGON_ARCH_VERSION >= 4
+#define arch_has_single_step() (1)
+#endif
+
+
 #endif
index 80504155ca3a72360c341eb522698d8d1d1152ee..fcdb5f96a984edfca7c222621bc5d291e01b2338 100644 (file)
@@ -211,6 +211,9 @@ struct pt_regs {
 #define pt_psp(regs) ((regs)->hvmer.vmpsp)
 #define pt_badva(regs) ((regs)->hvmer.vmbadva)
 
+#define pt_set_singlestep(regs) ((regs)->hvmer.vmest |= (1<<HVM_VMEST_SS_SFT))
+#define pt_clr_singlestep(regs) ((regs)->hvmer.vmest &= ~(1<<HVM_VMEST_SS_SFT))
+
 #define pt_set_rte_sp(regs, sp) do {\
        pt_psp(regs) = (sp);\
        (regs)->SP = (unsigned long) &((regs)->hvmer);\
index 3982d9c9ec2bfaad890192298e76b113f6a2ec3e..70df50d797d8ddcbb5009e0e2870b65a05901a2e 100644 (file)
 
 #include <asm/user.h>
 
+#if arch_has_single_step()
+/*  Both called from ptrace_resume  */
+void user_enable_single_step(struct task_struct *child)
+{
+       pt_set_singlestep(task_pt_regs(child));
+       set_tsk_thread_flag(child, TIF_SINGLESTEP);
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+       pt_clr_singlestep(task_pt_regs(child));
+       clear_tsk_thread_flag(child, TIF_SINGLESTEP);
+}
+#endif
+
 static int genregs_get(struct task_struct *target,
                   const struct user_regset *regset,
                   unsigned int pos, unsigned int count,
index 12164a30e8ff41268638efa3aefeb5d681b7f325..c2eeeef553356f4623fee455147d2b8b9a1d749b 100644 (file)
@@ -451,3 +451,14 @@ void do_machcheck(struct pt_regs *regs)
        /* Halt and catch fire */
        __vmstop();
 }
+
+/*
+ * Treat this like the old 0xdb trap.
+ */
+
+void do_debug_exception(struct pt_regs *regs)
+{
+       regs->hvmer.vmest &= ~HVM_VMEST_CAUSE_MSK;
+       regs->hvmer.vmest |= (TRAP_DEBUG << HVM_VMEST_CAUSE_SFT);
+       do_trap0(regs);
+}
index 053551ee7114012bc3b459a2a9922fd4f2a7c444..9add73ab57d873be21cd261c6f70aa3d2cb7466d 100644 (file)
@@ -367,6 +367,9 @@ _K_enter_trap0:
 _K_enter_machcheck:
        vm_event_entry(do_machcheck)
 
+       .globl _K_enter_debug
+_K_enter_debug:
+       vm_event_entry(do_debug_exception)
 
        .globl ret_from_fork
 ret_from_fork:
index 620f42cc582a17180083058a001d3464b57ac907..aff4054a2cff7c31e195dd1df3d1751dc94ccc9a 100644 (file)
@@ -41,7 +41,7 @@ _K_VM_event_vector:
        jump 1b;  /*  Reset  */
        jump _K_enter_machcheck;
        jump _K_enter_genex;
-       jump 1b;  /*  3 Rsvd  */
+       jump _K_enter_debug;
        jump 1b;  /*  4 Rsvd  */
        jump _K_enter_trap0;
        jump 1b;  /*  6 Rsvd  */