Message ID | 20230711121453.59138-11-philmd@linaro.org |
---|---|
State | New |
Headers | show |
Series | target/riscv: Allow building without TCG (KVM-only so far) | expand |
On Tue, Jul 11, 2023 at 10:21 PM Philippe Mathieu-Daudé <philmd@linaro.org> wrote: > > Extract TCG-specific code from debug.c to tcg/sysemu/debug.c, > restrict the prototypes to TCG, adapt meson rules. > > Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Acked-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > target/riscv/debug.h | 2 + > target/riscv/debug.c | 148 ------------------------- > target/riscv/tcg/sysemu/debug.c | 165 ++++++++++++++++++++++++++++ > target/riscv/tcg/meson.build | 2 + > target/riscv/tcg/sysemu/meson.build | 3 + > 5 files changed, 172 insertions(+), 148 deletions(-) > create mode 100644 target/riscv/tcg/sysemu/debug.c > create mode 100644 target/riscv/tcg/sysemu/meson.build > > diff --git a/target/riscv/debug.h b/target/riscv/debug.h > index 65cd45b8f3..0b3bdd5be1 100644 > --- a/target/riscv/debug.h > +++ b/target/riscv/debug.h > @@ -139,9 +139,11 @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val); > > target_ulong tinfo_csr_read(CPURISCVState *env); > > +#ifdef CONFIG_TCG > void riscv_cpu_debug_excp_handler(CPUState *cs); > bool riscv_cpu_debug_check_breakpoint(CPUState *cs); > bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp); > +#endif > > void riscv_trigger_init(CPURISCVState *env); > > diff --git a/target/riscv/debug.c b/target/riscv/debug.c > index 5676f2c57e..45a2605d8a 100644 > --- a/target/riscv/debug.c > +++ b/target/riscv/debug.c > @@ -754,154 +754,6 @@ target_ulong tinfo_csr_read(CPURISCVState *env) > BIT(TRIGGER_TYPE_AD_MATCH6); > } > > -void riscv_cpu_debug_excp_handler(CPUState *cs) > -{ > - RISCVCPU *cpu = RISCV_CPU(cs); > - CPURISCVState *env = &cpu->env; > - > - if (cs->watchpoint_hit) { > - if (cs->watchpoint_hit->flags & BP_CPU) { > - do_trigger_action(env, DBG_ACTION_BP); > - } > - } else { > - if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) { > - do_trigger_action(env, DBG_ACTION_BP); > - } > - } > -} > - > -bool riscv_cpu_debug_check_breakpoint(CPUState *cs) > -{ > - RISCVCPU *cpu = RISCV_CPU(cs); > - CPURISCVState *env = &cpu->env; > - CPUBreakpoint *bp; > - target_ulong ctrl; > - target_ulong pc; > - int trigger_type; > - int i; > - > - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { > - for (i = 0; i < RV_MAX_TRIGGERS; i++) { > - trigger_type = get_trigger_type(env, i); > - > - switch (trigger_type) { > - case TRIGGER_TYPE_AD_MATCH: > - /* type 2 trigger cannot be fired in VU/VS mode */ > - if (env->virt_enabled) { > - return false; > - } > - > - ctrl = env->tdata1[i]; > - pc = env->tdata2[i]; > - > - if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) { > - /* check U/S/M bit against current privilege level */ > - if ((ctrl >> 3) & BIT(env->priv)) { > - return true; > - } > - } > - break; > - case TRIGGER_TYPE_AD_MATCH6: > - ctrl = env->tdata1[i]; > - pc = env->tdata2[i]; > - > - if ((ctrl & TYPE6_EXEC) && (bp->pc == pc)) { > - if (env->virt_enabled) { > - /* check VU/VS bit against current privilege level */ > - if ((ctrl >> 23) & BIT(env->priv)) { > - return true; > - } > - } else { > - /* check U/S/M bit against current privilege level */ > - if ((ctrl >> 3) & BIT(env->priv)) { > - return true; > - } > - } > - } > - break; > - default: > - /* other trigger types are not supported or irrelevant */ > - break; > - } > - } > - } > - > - return false; > -} > - > -bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) > -{ > - RISCVCPU *cpu = RISCV_CPU(cs); > - CPURISCVState *env = &cpu->env; > - target_ulong ctrl; > - target_ulong addr; > - int trigger_type; > - int flags; > - int i; > - > - for (i = 0; i < RV_MAX_TRIGGERS; i++) { > - trigger_type = get_trigger_type(env, i); > - > - switch (trigger_type) { > - case TRIGGER_TYPE_AD_MATCH: > - /* type 2 trigger cannot be fired in VU/VS mode */ > - if (env->virt_enabled) { > - return false; > - } > - > - ctrl = env->tdata1[i]; > - addr = env->tdata2[i]; > - flags = 0; > - > - if (ctrl & TYPE2_LOAD) { > - flags |= BP_MEM_READ; > - } > - if (ctrl & TYPE2_STORE) { > - flags |= BP_MEM_WRITE; > - } > - > - if ((wp->flags & flags) && (wp->vaddr == addr)) { > - /* check U/S/M bit against current privilege level */ > - if ((ctrl >> 3) & BIT(env->priv)) { > - return true; > - } > - } > - break; > - case TRIGGER_TYPE_AD_MATCH6: > - ctrl = env->tdata1[i]; > - addr = env->tdata2[i]; > - flags = 0; > - > - if (ctrl & TYPE6_LOAD) { > - flags |= BP_MEM_READ; > - } > - if (ctrl & TYPE6_STORE) { > - flags |= BP_MEM_WRITE; > - } > - > - if ((wp->flags & flags) && (wp->vaddr == addr)) { > - if (env->virt_enabled) { > - /* check VU/VS bit against current privilege level */ > - if ((ctrl >> 23) & BIT(env->priv)) { > - return true; > - } > - } else { > - /* check U/S/M bit against current privilege level */ > - if ((ctrl >> 3) & BIT(env->priv)) { > - return true; > - } > - } > - } > - break; > - default: > - /* other trigger types are not supported */ > - break; > - } > - } > - > - return false; > -} > - > void riscv_trigger_init(CPURISCVState *env) > { > target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0); > diff --git a/target/riscv/tcg/sysemu/debug.c b/target/riscv/tcg/sysemu/debug.c > new file mode 100644 > index 0000000000..cdd6744b3a > --- /dev/null > +++ b/target/riscv/tcg/sysemu/debug.c > @@ -0,0 +1,165 @@ > +/* > + * QEMU RISC-V Native Debug Support (TCG specific) > + * > + * Copyright (c) 2022 Wind River Systems, Inc. > + * > + * Author: > + * Bin Meng <bin.meng@windriver.com> > + * > + * This provides the native debug support via the Trigger Module, as defined > + * in the RISC-V Debug Specification: > + * https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#include "qemu/osdep.h" > +#include "cpu.h" > + > +void riscv_cpu_debug_excp_handler(CPUState *cs) > +{ > + RISCVCPU *cpu = RISCV_CPU(cs); > + CPURISCVState *env = &cpu->env; > + > + if (cs->watchpoint_hit) { > + if (cs->watchpoint_hit->flags & BP_CPU) { > + do_trigger_action(env, DBG_ACTION_BP); > + } > + } else { > + if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) { > + do_trigger_action(env, DBG_ACTION_BP); > + } > + } > +} > + > +bool riscv_cpu_debug_check_breakpoint(CPUState *cs) > +{ > + RISCVCPU *cpu = RISCV_CPU(cs); > + CPURISCVState *env = &cpu->env; > + CPUBreakpoint *bp; > + target_ulong ctrl; > + target_ulong pc; > + int trigger_type; > + int i; > + > + QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { > + for (i = 0; i < RV_MAX_TRIGGERS; i++) { > + trigger_type = get_trigger_type(env, i); > + > + switch (trigger_type) { > + case TRIGGER_TYPE_AD_MATCH: > + /* type 2 trigger cannot be fired in VU/VS mode */ > + if (env->virt_enabled) { > + return false; > + } > + > + ctrl = env->tdata1[i]; > + pc = env->tdata2[i]; > + > + if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) { > + /* check U/S/M bit against current privilege level */ > + if ((ctrl >> 3) & BIT(env->priv)) { > + return true; > + } > + } > + break; > + case TRIGGER_TYPE_AD_MATCH6: > + ctrl = env->tdata1[i]; > + pc = env->tdata2[i]; > + > + if ((ctrl & TYPE6_EXEC) && (bp->pc == pc)) { > + if (env->virt_enabled) { > + /* check VU/VS bit against current privilege level */ > + if ((ctrl >> 23) & BIT(env->priv)) { > + return true; > + } > + } else { > + /* check U/S/M bit against current privilege level */ > + if ((ctrl >> 3) & BIT(env->priv)) { > + return true; > + } > + } > + } > + break; > + default: > + /* other trigger types are not supported or irrelevant */ > + break; > + } > + } > + } > + > + return false; > +} > + > +bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) > +{ > + RISCVCPU *cpu = RISCV_CPU(cs); > + CPURISCVState *env = &cpu->env; > + target_ulong ctrl; > + target_ulong addr; > + int trigger_type; > + int flags; > + int i; > + > + for (i = 0; i < RV_MAX_TRIGGERS; i++) { > + trigger_type = get_trigger_type(env, i); > + > + switch (trigger_type) { > + case TRIGGER_TYPE_AD_MATCH: > + /* type 2 trigger cannot be fired in VU/VS mode */ > + if (env->virt_enabled) { > + return false; > + } > + > + ctrl = env->tdata1[i]; > + addr = env->tdata2[i]; > + flags = 0; > + > + if (ctrl & TYPE2_LOAD) { > + flags |= BP_MEM_READ; > + } > + if (ctrl & TYPE2_STORE) { > + flags |= BP_MEM_WRITE; > + } > + > + if ((wp->flags & flags) && (wp->vaddr == addr)) { > + /* check U/S/M bit against current privilege level */ > + if ((ctrl >> 3) & BIT(env->priv)) { > + return true; > + } > + } > + break; > + case TRIGGER_TYPE_AD_MATCH6: > + ctrl = env->tdata1[i]; > + addr = env->tdata2[i]; > + flags = 0; > + > + if (ctrl & TYPE6_LOAD) { > + flags |= BP_MEM_READ; > + } > + if (ctrl & TYPE6_STORE) { > + flags |= BP_MEM_WRITE; > + } > + > + if ((wp->flags & flags) && (wp->vaddr == addr)) { > + if (env->virt_enabled) { > + /* check VU/VS bit against current privilege level */ > + if ((ctrl >> 23) & BIT(env->priv)) { > + return true; > + } > + } else { > + /* check U/S/M bit against current privilege level */ > + if ((ctrl >> 3) & BIT(env->priv)) { > + return true; > + } > + } > + } > + break; > + default: > + /* other trigger types are not supported */ > + break; > + } > + } > + > + return false; > +} > diff --git a/target/riscv/tcg/meson.build b/target/riscv/tcg/meson.build > index a615aafd9a..933d340799 100644 > --- a/target/riscv/tcg/meson.build > +++ b/target/riscv/tcg/meson.build > @@ -18,3 +18,5 @@ riscv_ss.add(when: 'CONFIG_TCG', if_true: files( > 'crypto_helper.c', > 'zce_helper.c', > ), if_false: files('tcg-stub.c')) > + > +subdir('sysemu') > diff --git a/target/riscv/tcg/sysemu/meson.build b/target/riscv/tcg/sysemu/meson.build > new file mode 100644 > index 0000000000..e8e61e5784 > --- /dev/null > +++ b/target/riscv/tcg/sysemu/meson.build > @@ -0,0 +1,3 @@ > +riscv_system_ss.add(when: 'CONFIG_TCG', if_true: files( > + 'debug.c', > +)) > -- > 2.38.1 > >
diff --git a/target/riscv/debug.h b/target/riscv/debug.h index 65cd45b8f3..0b3bdd5be1 100644 --- a/target/riscv/debug.h +++ b/target/riscv/debug.h @@ -139,9 +139,11 @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val); target_ulong tinfo_csr_read(CPURISCVState *env); +#ifdef CONFIG_TCG void riscv_cpu_debug_excp_handler(CPUState *cs); bool riscv_cpu_debug_check_breakpoint(CPUState *cs); bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp); +#endif void riscv_trigger_init(CPURISCVState *env); diff --git a/target/riscv/debug.c b/target/riscv/debug.c index 5676f2c57e..45a2605d8a 100644 --- a/target/riscv/debug.c +++ b/target/riscv/debug.c @@ -754,154 +754,6 @@ target_ulong tinfo_csr_read(CPURISCVState *env) BIT(TRIGGER_TYPE_AD_MATCH6); } -void riscv_cpu_debug_excp_handler(CPUState *cs) -{ - RISCVCPU *cpu = RISCV_CPU(cs); - CPURISCVState *env = &cpu->env; - - if (cs->watchpoint_hit) { - if (cs->watchpoint_hit->flags & BP_CPU) { - do_trigger_action(env, DBG_ACTION_BP); - } - } else { - if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) { - do_trigger_action(env, DBG_ACTION_BP); - } - } -} - -bool riscv_cpu_debug_check_breakpoint(CPUState *cs) -{ - RISCVCPU *cpu = RISCV_CPU(cs); - CPURISCVState *env = &cpu->env; - CPUBreakpoint *bp; - target_ulong ctrl; - target_ulong pc; - int trigger_type; - int i; - - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { - for (i = 0; i < RV_MAX_TRIGGERS; i++) { - trigger_type = get_trigger_type(env, i); - - switch (trigger_type) { - case TRIGGER_TYPE_AD_MATCH: - /* type 2 trigger cannot be fired in VU/VS mode */ - if (env->virt_enabled) { - return false; - } - - ctrl = env->tdata1[i]; - pc = env->tdata2[i]; - - if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) { - /* check U/S/M bit against current privilege level */ - if ((ctrl >> 3) & BIT(env->priv)) { - return true; - } - } - break; - case TRIGGER_TYPE_AD_MATCH6: - ctrl = env->tdata1[i]; - pc = env->tdata2[i]; - - if ((ctrl & TYPE6_EXEC) && (bp->pc == pc)) { - if (env->virt_enabled) { - /* check VU/VS bit against current privilege level */ - if ((ctrl >> 23) & BIT(env->priv)) { - return true; - } - } else { - /* check U/S/M bit against current privilege level */ - if ((ctrl >> 3) & BIT(env->priv)) { - return true; - } - } - } - break; - default: - /* other trigger types are not supported or irrelevant */ - break; - } - } - } - - return false; -} - -bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) -{ - RISCVCPU *cpu = RISCV_CPU(cs); - CPURISCVState *env = &cpu->env; - target_ulong ctrl; - target_ulong addr; - int trigger_type; - int flags; - int i; - - for (i = 0; i < RV_MAX_TRIGGERS; i++) { - trigger_type = get_trigger_type(env, i); - - switch (trigger_type) { - case TRIGGER_TYPE_AD_MATCH: - /* type 2 trigger cannot be fired in VU/VS mode */ - if (env->virt_enabled) { - return false; - } - - ctrl = env->tdata1[i]; - addr = env->tdata2[i]; - flags = 0; - - if (ctrl & TYPE2_LOAD) { - flags |= BP_MEM_READ; - } - if (ctrl & TYPE2_STORE) { - flags |= BP_MEM_WRITE; - } - - if ((wp->flags & flags) && (wp->vaddr == addr)) { - /* check U/S/M bit against current privilege level */ - if ((ctrl >> 3) & BIT(env->priv)) { - return true; - } - } - break; - case TRIGGER_TYPE_AD_MATCH6: - ctrl = env->tdata1[i]; - addr = env->tdata2[i]; - flags = 0; - - if (ctrl & TYPE6_LOAD) { - flags |= BP_MEM_READ; - } - if (ctrl & TYPE6_STORE) { - flags |= BP_MEM_WRITE; - } - - if ((wp->flags & flags) && (wp->vaddr == addr)) { - if (env->virt_enabled) { - /* check VU/VS bit against current privilege level */ - if ((ctrl >> 23) & BIT(env->priv)) { - return true; - } - } else { - /* check U/S/M bit against current privilege level */ - if ((ctrl >> 3) & BIT(env->priv)) { - return true; - } - } - } - break; - default: - /* other trigger types are not supported */ - break; - } - } - - return false; -} - void riscv_trigger_init(CPURISCVState *env) { target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0); diff --git a/target/riscv/tcg/sysemu/debug.c b/target/riscv/tcg/sysemu/debug.c new file mode 100644 index 0000000000..cdd6744b3a --- /dev/null +++ b/target/riscv/tcg/sysemu/debug.c @@ -0,0 +1,165 @@ +/* + * QEMU RISC-V Native Debug Support (TCG specific) + * + * Copyright (c) 2022 Wind River Systems, Inc. + * + * Author: + * Bin Meng <bin.meng@windriver.com> + * + * This provides the native debug support via the Trigger Module, as defined + * in the RISC-V Debug Specification: + * https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "cpu.h" + +void riscv_cpu_debug_excp_handler(CPUState *cs) +{ + RISCVCPU *cpu = RISCV_CPU(cs); + CPURISCVState *env = &cpu->env; + + if (cs->watchpoint_hit) { + if (cs->watchpoint_hit->flags & BP_CPU) { + do_trigger_action(env, DBG_ACTION_BP); + } + } else { + if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) { + do_trigger_action(env, DBG_ACTION_BP); + } + } +} + +bool riscv_cpu_debug_check_breakpoint(CPUState *cs) +{ + RISCVCPU *cpu = RISCV_CPU(cs); + CPURISCVState *env = &cpu->env; + CPUBreakpoint *bp; + target_ulong ctrl; + target_ulong pc; + int trigger_type; + int i; + + QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { + for (i = 0; i < RV_MAX_TRIGGERS; i++) { + trigger_type = get_trigger_type(env, i); + + switch (trigger_type) { + case TRIGGER_TYPE_AD_MATCH: + /* type 2 trigger cannot be fired in VU/VS mode */ + if (env->virt_enabled) { + return false; + } + + ctrl = env->tdata1[i]; + pc = env->tdata2[i]; + + if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) { + /* check U/S/M bit against current privilege level */ + if ((ctrl >> 3) & BIT(env->priv)) { + return true; + } + } + break; + case TRIGGER_TYPE_AD_MATCH6: + ctrl = env->tdata1[i]; + pc = env->tdata2[i]; + + if ((ctrl & TYPE6_EXEC) && (bp->pc == pc)) { + if (env->virt_enabled) { + /* check VU/VS bit against current privilege level */ + if ((ctrl >> 23) & BIT(env->priv)) { + return true; + } + } else { + /* check U/S/M bit against current privilege level */ + if ((ctrl >> 3) & BIT(env->priv)) { + return true; + } + } + } + break; + default: + /* other trigger types are not supported or irrelevant */ + break; + } + } + } + + return false; +} + +bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) +{ + RISCVCPU *cpu = RISCV_CPU(cs); + CPURISCVState *env = &cpu->env; + target_ulong ctrl; + target_ulong addr; + int trigger_type; + int flags; + int i; + + for (i = 0; i < RV_MAX_TRIGGERS; i++) { + trigger_type = get_trigger_type(env, i); + + switch (trigger_type) { + case TRIGGER_TYPE_AD_MATCH: + /* type 2 trigger cannot be fired in VU/VS mode */ + if (env->virt_enabled) { + return false; + } + + ctrl = env->tdata1[i]; + addr = env->tdata2[i]; + flags = 0; + + if (ctrl & TYPE2_LOAD) { + flags |= BP_MEM_READ; + } + if (ctrl & TYPE2_STORE) { + flags |= BP_MEM_WRITE; + } + + if ((wp->flags & flags) && (wp->vaddr == addr)) { + /* check U/S/M bit against current privilege level */ + if ((ctrl >> 3) & BIT(env->priv)) { + return true; + } + } + break; + case TRIGGER_TYPE_AD_MATCH6: + ctrl = env->tdata1[i]; + addr = env->tdata2[i]; + flags = 0; + + if (ctrl & TYPE6_LOAD) { + flags |= BP_MEM_READ; + } + if (ctrl & TYPE6_STORE) { + flags |= BP_MEM_WRITE; + } + + if ((wp->flags & flags) && (wp->vaddr == addr)) { + if (env->virt_enabled) { + /* check VU/VS bit against current privilege level */ + if ((ctrl >> 23) & BIT(env->priv)) { + return true; + } + } else { + /* check U/S/M bit against current privilege level */ + if ((ctrl >> 3) & BIT(env->priv)) { + return true; + } + } + } + break; + default: + /* other trigger types are not supported */ + break; + } + } + + return false; +} diff --git a/target/riscv/tcg/meson.build b/target/riscv/tcg/meson.build index a615aafd9a..933d340799 100644 --- a/target/riscv/tcg/meson.build +++ b/target/riscv/tcg/meson.build @@ -18,3 +18,5 @@ riscv_ss.add(when: 'CONFIG_TCG', if_true: files( 'crypto_helper.c', 'zce_helper.c', ), if_false: files('tcg-stub.c')) + +subdir('sysemu') diff --git a/target/riscv/tcg/sysemu/meson.build b/target/riscv/tcg/sysemu/meson.build new file mode 100644 index 0000000000..e8e61e5784 --- /dev/null +++ b/target/riscv/tcg/sysemu/meson.build @@ -0,0 +1,3 @@ +riscv_system_ss.add(when: 'CONFIG_TCG', if_true: files( + 'debug.c', +))
Extract TCG-specific code from debug.c to tcg/sysemu/debug.c, restrict the prototypes to TCG, adapt meson rules. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> --- target/riscv/debug.h | 2 + target/riscv/debug.c | 148 ------------------------- target/riscv/tcg/sysemu/debug.c | 165 ++++++++++++++++++++++++++++ target/riscv/tcg/meson.build | 2 + target/riscv/tcg/sysemu/meson.build | 3 + 5 files changed, 172 insertions(+), 148 deletions(-) create mode 100644 target/riscv/tcg/sysemu/debug.c create mode 100644 target/riscv/tcg/sysemu/meson.build