[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL v3 11/43] target/riscv: Add itrigger support when icount is enable
From: |
Alistair Francis |
Subject: |
[PULL v3 11/43] target/riscv: Add itrigger support when icount is enabled |
Date: |
Fri, 6 Jan 2023 13:13:25 +1000 |
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
The max count in itrigger can be 0x3FFF, which will cause a no trivial
translation and execution overload.
When icount is enabled, QEMU provides API that can fetch guest
instruction number. Thus, we can set an timer for itrigger with
the count as deadline.
Only when timer expires or priviledge mode changes, do lazy update
to count.
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20221013062946.7530-3-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 2 ++
target/riscv/debug.h | 1 +
target/riscv/cpu_helper.c | 3 ++
target/riscv/debug.c | 59 +++++++++++++++++++++++++++++++++++++++
4 files changed, 65 insertions(+)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index c32e484c0b..b0b4048de9 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -329,6 +329,8 @@ struct CPUArchState {
target_ulong tdata3[RV_MAX_TRIGGERS];
struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
+ QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
+ int64_t last_icount;
/* machine specific rdtime callback */
uint64_t (*rdtime_fn)(void *);
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
index cc3358e69b..c471748d5a 100644
--- a/target/riscv/debug.h
+++ b/target/riscv/debug.h
@@ -146,4 +146,5 @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs,
CPUWatchpoint *wp);
void riscv_trigger_init(CPURISCVState *env);
bool riscv_itrigger_enabled(CPURISCVState *env);
+void riscv_itrigger_update_priv(CPURISCVState *env);
#endif /* RISCV_DEBUG_H */
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9d1d1bf9f1..6230f65f70 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -676,6 +676,9 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong
newpriv)
if (newpriv == PRV_H) {
newpriv = PRV_U;
}
+ if (icount_enabled() && newpriv != env->priv) {
+ riscv_itrigger_update_priv(env);
+ }
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
env->priv = newpriv;
env->xl = cpu_recompute_xl(env);
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 036161649f..371862cf38 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -30,6 +30,7 @@
#include "trace.h"
#include "exec/exec-all.h"
#include "exec/helper-proto.h"
+#include "sysemu/cpu-timers.h"
/*
* The following M-mode trigger CSRs are implemented:
@@ -567,6 +568,62 @@ void helper_itrigger_match(CPURISCVState *env)
}
}
+static void riscv_itrigger_update_count(CPURISCVState *env)
+{
+ int count, executed;
+ /*
+ * Record last icount, so that we can evaluate the executed instructions
+ * since last priviledge mode change or timer expire.
+ */
+ int64_t last_icount = env->last_icount, current_icount;
+ current_icount = env->last_icount = icount_get_raw();
+
+ for (int i = 0; i < RV_MAX_TRIGGERS; i++) {
+ if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
+ continue;
+ }
+ count = itrigger_get_count(env, i);
+ if (!count) {
+ continue;
+ }
+ /*
+ * Only when priviledge is changed or itrigger timer expires,
+ * the count field in itrigger tdata1 register is updated.
+ * And the count field in itrigger only contains remaining value.
+ */
+ if (check_itrigger_priv(env, i)) {
+ /*
+ * If itrigger enabled in this priviledge mode, the number of
+ * executed instructions since last priviledge change
+ * should be reduced from current itrigger count.
+ */
+ executed = current_icount - last_icount;
+ itrigger_set_count(env, i, count - executed);
+ if (count == executed) {
+ do_trigger_action(env, i);
+ }
+ } else {
+ /*
+ * If itrigger is not enabled in this priviledge mode,
+ * the number of executed instructions will be discard and
+ * the count field in itrigger will not change.
+ */
+ timer_mod(env->itrigger_timer[i],
+ current_icount + count);
+ }
+ }
+}
+
+static void riscv_itrigger_timer_cb(void *opaque)
+{
+ riscv_itrigger_update_count((CPURISCVState *)opaque);
+}
+
+void riscv_itrigger_update_priv(CPURISCVState *env)
+{
+ riscv_itrigger_update_count(env);
+}
+
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
{
switch (tdata_index) {
@@ -796,5 +853,7 @@ void riscv_trigger_init(CPURISCVState *env)
env->tdata3[i] = 0;
env->cpu_breakpoint[i] = NULL;
env->cpu_watchpoint[i] = NULL;
+ env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+ riscv_itrigger_timer_cb, env);
}
}
--
2.39.0
- [PULL v3 02/43] tcg/riscv: Fix range matched by TCG_CT_CONST_M12, (continued)
- [PULL v3 02/43] tcg/riscv: Fix range matched by TCG_CT_CONST_M12, Alistair Francis, 2023/01/05
- [PULL v3 03/43] tcg/riscv: Fix reg overlap case in tcg_out_addsub2, Alistair Francis, 2023/01/05
- [PULL v3 01/43] target/riscv: Fix PMP propagation for tlb, Alistair Francis, 2023/01/05
- [PULL v3 04/43] tcg/riscv: Fix base register for user-only qemu_ld/st, Alistair Francis, 2023/01/05
- [PULL v3 05/43] hw/riscv/opentitan: bump opentitan, Alistair Francis, 2023/01/05
- [PULL v3 06/43] hw/riscv/opentitan: add aon_timer base unimpl, Alistair Francis, 2023/01/05
- [PULL v3 07/43] target/riscv: Add smstateen support, Alistair Francis, 2023/01/05
- [PULL v3 09/43] target/riscv: generate virtual instruction exception, Alistair Francis, 2023/01/05
- [PULL v3 10/43] target/riscv: Add itrigger support when icount is not enabled, Alistair Francis, 2023/01/05
- [PULL v3 08/43] target/riscv: smstateen check for h/s/envcfg, Alistair Francis, 2023/01/05
- [PULL v3 11/43] target/riscv: Add itrigger support when icount is enabled,
Alistair Francis <=
- [PULL v3 12/43] target/riscv: Enable native debug itrigger, Alistair Francis, 2023/01/05
- [PULL v3 13/43] target/riscv: Add itrigger_enabled field to CPURISCVState, Alistair Francis, 2023/01/05
- [PULL v3 14/43] hw/intc: sifive_plic: Renumber the S irqs for numa support, Alistair Francis, 2023/01/05
- [PULL v3 15/43] target/riscv: Typo fix in sstc() predicate, Alistair Francis, 2023/01/05
- [PULL v3 16/43] hw/riscv: virt: Remove the redundant ipi-id property, Alistair Francis, 2023/01/05
- [PULL v3 18/43] target/riscv: Add some comments for sstatus CSR in riscv_cpu_dump_state(), Alistair Francis, 2023/01/05
- [PULL v3 17/43] target/riscv: support cache-related PMU events in virtual mode, Alistair Francis, 2023/01/05
- [PULL v3 22/43] hw/intc: sifive_plic: fix out-of-bound access of source_priority array, Alistair Francis, 2023/01/05
- [PULL v3 19/43] hw/misc: pfsoc: add fabric clocks to ioscb, Alistair Francis, 2023/01/05
- [PULL v3 21/43] hw/{misc, riscv}: pfsoc: add system controller as unimplemented, Alistair Francis, 2023/01/05