Skip to content

Commit 815ca1d

Browse files
committed
riscv: andes: trigger_module: Add Andes trigge moduler support for ptrace single-step (torvalds#198)
Signed-off-by: charles <[email protected]> Reviewed-on: https://gitea.andestech.com/RD-SW/linux/pulls/198 Reviewed-by: Tim Shih-Ting OuYang <[email protected]> Reviewed-by: Ben Zong-You Xie <[email protected]> Co-authored-by: charles <[email protected]> Co-committed-by: charles <[email protected]>
1 parent 949eeb0 commit 815ca1d

File tree

8 files changed

+85
-0
lines changed

8 files changed

+85
-0
lines changed

arch/riscv/include/asm/entry-common.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,23 @@
44
#define _ASM_RISCV_ENTRY_COMMON_H
55

66
#include <asm/stacktrace.h>
7+
#include <linux/soc/andes/csr.h>
8+
#include <linux/soc/andes/trigger_module.h>
79

810
void handle_page_fault(struct pt_regs *regs);
911
void handle_break(struct pt_regs *regs);
1012

13+
static __always_inline void arch_exit_to_user_mode_work(struct pt_regs *regs,
14+
unsigned long ti_work)
15+
{
16+
if (static_branch_unlikely(&trigger_module_single_step_key)) {
17+
if (ti_work & _TIF_SINGLESTEP) {
18+
sbi_andes_set_trigger(TRIGGER_TYPE_ICOUNT, ICOUNT, 1);
19+
csr_write(CSR_SCONTEXT, 1);
20+
} else {
21+
csr_write(CSR_SCONTEXT, 0);
22+
}
23+
}
24+
}
25+
#define arch_exit_to_user_mode_work arch_exit_to_user_mode_work
1126
#endif /* _ASM_RISCV_ENTRY_COMMON_H */

arch/riscv/include/asm/ptrace.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ struct pt_regs {
6565
#define REG_FMT "%08lx"
6666
#endif
6767

68+
/* Andes use trigger module to implement the ptrace single step. */
69+
#define arch_has_single_step() (1)
70+
6871
#define user_mode(regs) (((regs)->status & SR_PP) == 0)
6972

7073
#define MAX_REG_OFFSET offsetof(struct pt_regs, orig_a0)

arch/riscv/include/asm/thread_info.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
8787
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
8888
#define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */
8989
#define TIF_MEMDIE 5 /* is terminating due to OOM killer */
90+
#define TIF_SINGLESTEP 6 /* Andes trigger module support ptrace single step */
9091
#define TIF_NOTIFY_SIGNAL 9 /* signal notifications exist */
9192
#define TIF_UPROBE 10 /* uprobe breakpoint or singlestep */
9293
#define TIF_32BIT 11 /* compat-mode 32bit process */
@@ -96,6 +97,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
9697
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
9798
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
9899
#define _TIF_UPROBE (1 << TIF_UPROBE)
100+
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
99101

100102
#define _TIF_WORK_MASK \
101103
(_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NEED_RESCHED | \

drivers/soc/andes/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
obj-y += andes_sbi.o
55
obj-y += inject_init.o
66
obj-y += dcause.o
7+
obj-y += trigger_module.o
78
obj-$(CONFIG_ANDES_PPMA) += ppma.o
89
obj-$(CONFIG_ANDES_ATCSMU) += atcsmu.o

drivers/soc/andes/andes_sbi.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ long sbi_andes_read_powerbrake(void)
4747
return ret.value;
4848
}
4949
EXPORT_SYMBOL(sbi_andes_read_powerbrake);
50+
51+
/* trigger module support debug application with gdbserver */
52+
void sbi_andes_set_trigger(unsigned int type, uintptr_t data, int enable)
53+
{
54+
sbi_ecall(ANDES_SBI_EXT_ANDES, SBI_EXT_ANDES_TRIGGER_SET,
55+
type, data, enable, 0, 0, 0);
56+
}
57+
EXPORT_SYMBOL(sbi_andes_set_trigger);

drivers/soc/andes/trigger_module.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Copyright (C) 2024 Andes Technology Corporation.
4+
*/
5+
#include <asm/cacheflush.h>
6+
#include <linux/soc/andes/csr.h>
7+
#include <linux/soc/andes/trigger_module.h>
8+
9+
DEFINE_STATIC_KEY_FALSE(trigger_module_single_step_key);
10+
11+
void user_enable_single_step(struct task_struct *child)
12+
{
13+
if (static_branch_unlikely(&trigger_module_single_step_key)) {
14+
if (!test_tsk_thread_flag(child, TIF_SINGLESTEP))
15+
static_branch_disable(&trigger_module_single_step_key);
16+
} else {
17+
static_branch_enable(&trigger_module_single_step_key);
18+
}
19+
20+
set_tsk_thread_flag(child, TIF_SINGLESTEP);
21+
}
22+
23+
void user_disable_single_step(struct task_struct *child)
24+
{
25+
if (static_branch_unlikely(&trigger_module_single_step_key) &&
26+
test_tsk_thread_flag(child, TIF_SINGLESTEP))
27+
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
28+
}

include/linux/soc/andes/sbi.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,13 @@ long sbi_andes_probe_ppma(void);
5050
void sbi_andes_write_powerbrake(unsigned int val);
5151
long sbi_andes_read_powerbrake(void);
5252

53+
#ifdef CONFIG_ARCH_ANDES
54+
/* Trigger module support debug application with gdbserver */
55+
void sbi_andes_set_trigger(unsigned int type, uintptr_t data, int enable);
56+
#else
57+
static inline void sbi_andes_set_trigger(unsigned int type,
58+
uintptr_t data,
59+
int enable) {}
60+
#endif /* !CONFIG_ARCH_ANDES */
61+
5362
#endif /* !__LINUX_SOC_ANDES_SBI_H */
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* Copyright (C) 2023 Andes Technology Corporation.
4+
*/
5+
6+
#ifndef __LINUX_SOC_ANDES_TRIGGER_MODULE_H
7+
#define __LINUX_SOC_ANDES_TRIGGER_MODULE_H
8+
9+
#include <linux/soc/andes/sbi.h>
10+
11+
#define TRIGGER_TYPE_ICOUNT 3
12+
#define ICOUNT 1
13+
14+
DECLARE_STATIC_KEY_FALSE(trigger_module_single_step_key);
15+
16+
void user_enable_single_step(struct task_struct *);
17+
void user_disable_single_step(struct task_struct *);
18+
19+
#endif /* !__LINUX_SOC_ANDES_TRIGGER_MODULE_H */

0 commit comments

Comments
 (0)