diff options
author | Richard Kuo <rkuo@codeaurora.org> | 2013-03-07 13:03:10 -0500 |
---|---|---|
committer | Richard Kuo <rkuo@codeaurora.org> | 2013-04-30 20:40:25 -0400 |
commit | 7777746c40876834c1527689336e43c8381b1921 (patch) | |
tree | b3257768e29db418ab9292a4e9a27c56e1e88fed /arch/hexagon | |
parent | f8722a4d5243e779d6795e2d775c9114c44a6c26 (diff) |
Hexagon: add support for single-stepping (v4+)
Hardware single-step is only available on v4 and later
architectures.
Signed-off-by: Richard Kuo <rkuo@codeaurora.org>
Diffstat (limited to 'arch/hexagon')
-rw-r--r-- | arch/hexagon/include/uapi/asm/ptrace.h | 5 | ||||
-rw-r--r-- | arch/hexagon/include/uapi/asm/registers.h | 3 | ||||
-rw-r--r-- | arch/hexagon/kernel/ptrace.c | 15 | ||||
-rw-r--r-- | arch/hexagon/kernel/traps.c | 11 | ||||
-rw-r--r-- | arch/hexagon/kernel/vm_entry.S | 3 | ||||
-rw-r--r-- | arch/hexagon/kernel/vm_vectors.S | 2 |
6 files changed, 38 insertions, 1 deletions
diff --git a/arch/hexagon/include/uapi/asm/ptrace.h b/arch/hexagon/include/uapi/asm/ptrace.h index 1ffce0c6ee07..065e5b32313f 100644 --- a/arch/hexagon/include/uapi/asm/ptrace.h +++ b/arch/hexagon/include/uapi/asm/ptrace.h | |||
@@ -36,4 +36,9 @@ extern const char *regs_query_register_name(unsigned int offset); | |||
36 | ((struct pt_regs *) \ | 36 | ((struct pt_regs *) \ |
37 | ((unsigned long)current_thread_info() + THREAD_SIZE) - 1) | 37 | ((unsigned long)current_thread_info() + THREAD_SIZE) - 1) |
38 | 38 | ||
39 | #if CONFIG_HEXAGON_ARCH_VERSION >= 4 | ||
40 | #define arch_has_single_step() (1) | ||
41 | #endif | ||
42 | |||
43 | |||
39 | #endif | 44 | #endif |
diff --git a/arch/hexagon/include/uapi/asm/registers.h b/arch/hexagon/include/uapi/asm/registers.h index 80504155ca3a..fcdb5f96a984 100644 --- a/arch/hexagon/include/uapi/asm/registers.h +++ b/arch/hexagon/include/uapi/asm/registers.h | |||
@@ -211,6 +211,9 @@ struct pt_regs { | |||
211 | #define pt_psp(regs) ((regs)->hvmer.vmpsp) | 211 | #define pt_psp(regs) ((regs)->hvmer.vmpsp) |
212 | #define pt_badva(regs) ((regs)->hvmer.vmbadva) | 212 | #define pt_badva(regs) ((regs)->hvmer.vmbadva) |
213 | 213 | ||
214 | #define pt_set_singlestep(regs) ((regs)->hvmer.vmest |= (1<<HVM_VMEST_SS_SFT)) | ||
215 | #define pt_clr_singlestep(regs) ((regs)->hvmer.vmest &= ~(1<<HVM_VMEST_SS_SFT)) | ||
216 | |||
214 | #define pt_set_rte_sp(regs, sp) do {\ | 217 | #define pt_set_rte_sp(regs, sp) do {\ |
215 | pt_psp(regs) = (sp);\ | 218 | pt_psp(regs) = (sp);\ |
216 | (regs)->SP = (unsigned long) &((regs)->hvmer);\ | 219 | (regs)->SP = (unsigned long) &((regs)->hvmer);\ |
diff --git a/arch/hexagon/kernel/ptrace.c b/arch/hexagon/kernel/ptrace.c index 3982d9c9ec2b..70df50d797d8 100644 --- a/arch/hexagon/kernel/ptrace.c +++ b/arch/hexagon/kernel/ptrace.c | |||
@@ -32,6 +32,21 @@ | |||
32 | 32 | ||
33 | #include <asm/user.h> | 33 | #include <asm/user.h> |
34 | 34 | ||
35 | #if arch_has_single_step() | ||
36 | /* Both called from ptrace_resume */ | ||
37 | void user_enable_single_step(struct task_struct *child) | ||
38 | { | ||
39 | pt_set_singlestep(task_pt_regs(child)); | ||
40 | set_tsk_thread_flag(child, TIF_SINGLESTEP); | ||
41 | } | ||
42 | |||
43 | void user_disable_single_step(struct task_struct *child) | ||
44 | { | ||
45 | pt_clr_singlestep(task_pt_regs(child)); | ||
46 | clear_tsk_thread_flag(child, TIF_SINGLESTEP); | ||
47 | } | ||
48 | #endif | ||
49 | |||
35 | static int genregs_get(struct task_struct *target, | 50 | static int genregs_get(struct task_struct *target, |
36 | const struct user_regset *regset, | 51 | const struct user_regset *regset, |
37 | unsigned int pos, unsigned int count, | 52 | unsigned int pos, unsigned int count, |
diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c index 12164a30e8ff..c2eeeef55335 100644 --- a/arch/hexagon/kernel/traps.c +++ b/arch/hexagon/kernel/traps.c | |||
@@ -451,3 +451,14 @@ void do_machcheck(struct pt_regs *regs) | |||
451 | /* Halt and catch fire */ | 451 | /* Halt and catch fire */ |
452 | __vmstop(); | 452 | __vmstop(); |
453 | } | 453 | } |
454 | |||
455 | /* | ||
456 | * Treat this like the old 0xdb trap. | ||
457 | */ | ||
458 | |||
459 | void do_debug_exception(struct pt_regs *regs) | ||
460 | { | ||
461 | regs->hvmer.vmest &= ~HVM_VMEST_CAUSE_MSK; | ||
462 | regs->hvmer.vmest |= (TRAP_DEBUG << HVM_VMEST_CAUSE_SFT); | ||
463 | do_trap0(regs); | ||
464 | } | ||
diff --git a/arch/hexagon/kernel/vm_entry.S b/arch/hexagon/kernel/vm_entry.S index 053551ee7114..9add73ab57d8 100644 --- a/arch/hexagon/kernel/vm_entry.S +++ b/arch/hexagon/kernel/vm_entry.S | |||
@@ -367,6 +367,9 @@ _K_enter_trap0: | |||
367 | _K_enter_machcheck: | 367 | _K_enter_machcheck: |
368 | vm_event_entry(do_machcheck) | 368 | vm_event_entry(do_machcheck) |
369 | 369 | ||
370 | .globl _K_enter_debug | ||
371 | _K_enter_debug: | ||
372 | vm_event_entry(do_debug_exception) | ||
370 | 373 | ||
371 | .globl ret_from_fork | 374 | .globl ret_from_fork |
372 | ret_from_fork: | 375 | ret_from_fork: |
diff --git a/arch/hexagon/kernel/vm_vectors.S b/arch/hexagon/kernel/vm_vectors.S index 620f42cc582a..aff4054a2cff 100644 --- a/arch/hexagon/kernel/vm_vectors.S +++ b/arch/hexagon/kernel/vm_vectors.S | |||
@@ -41,7 +41,7 @@ _K_VM_event_vector: | |||
41 | jump 1b; /* Reset */ | 41 | jump 1b; /* Reset */ |
42 | jump _K_enter_machcheck; | 42 | jump _K_enter_machcheck; |
43 | jump _K_enter_genex; | 43 | jump _K_enter_genex; |
44 | jump 1b; /* 3 Rsvd */ | 44 | jump _K_enter_debug; |
45 | jump 1b; /* 4 Rsvd */ | 45 | jump 1b; /* 4 Rsvd */ |
46 | jump _K_enter_trap0; | 46 | jump _K_enter_trap0; |
47 | jump 1b; /* 6 Rsvd */ | 47 | jump 1b; /* 6 Rsvd */ |