Hi,
On 26/5/26 04:48, Zephyr Li wrote:
Building riscv64-softmmu with --disable-tcg currently fails because
RISC-V still builds or references TCG-only sources and helpers in the
no-TCG configuration.
Move TCG-only helper and translator sources under CONFIG_TCG, guard the
remaining TCG-only code in common files, and move common CSR helpers out
of TCG-only helper files.
misa writes still rely on the TCG extension validation path. Since
x-misa-w is a TCG-only experimental property, reject it during CPU
realize when TCG is not available.
Please split as one logical change per patch (i.e. moving FPU flags
in one, exception path in another, ...).
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3483
Signed-off-by: Zephyr Li <[email protected]>
---
Testing:
- riscv64-softmmu --enable-kvm --disable-tcg --enable-debug builds
successfully.
- riscv64-softmmu --enable-debug builds successfully.
- qemu-system-riscv64 -M virt,accel=qtest -cpu rv64,x-misa-w=true \
-S -nographic reports "x-misa-w requires TCG".
target/riscv/cpu.c | 9 +++++++
target/riscv/cpu_helper.c | 53 +++++++++++++++++++++++++++++++++++++++
target/riscv/csr.c | 18 +++++++++++--
target/riscv/fpu_helper.c | 27 --------------------
target/riscv/meson.build | 9 ++++---
target/riscv/op_helper.c | 15 -----------
6 files changed, 84 insertions(+), 47 deletions(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 862834b480..3f4563fce2 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -36,7 +36,9 @@
#include "system/tcg.h"
#include "kvm/kvm_riscv.h"
#include "tcg/tcg-cpu.h"
+#ifdef CONFIG_TCG
#include "tcg/tcg.h"
Apparently this header isn't needed at all.
+#endif
/* RISC-V CPU definitions */
static const char riscv_single_letter_exts[] = "IEMAFDQCBPVH";
@@ -956,6 +958,13 @@ static void riscv_cpu_realize(DeviceState *dev, Error
**errp)
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
Error *local_err = NULL;
+#ifndef CONFIG_TCG
+ if (cpu->cfg.misa_w) {
+ error_setg(errp, "x-misa-w requires TCG");
+ return;
+ }
+#endif
+
cpu_exec_realizefn(cs, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 17305e1bb7..e53a5d567d 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -21,6 +21,7 @@
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "cpu.h"
+#include "fpu/softfloat.h"
#include "internals.h"
#include "pmu.h"
#include "exec/cputlb.h"
@@ -28,8 +29,10 @@
#include "exec/target_page.h"
#include "system/memory.h"
#include "instmap.h"
+#ifdef CONFIG_TCG
#include "tcg/tcg-op.h"
#include "accel/tcg/cpu-ops.h"
+#endif
#include "trace.h"
#include "semihosting/common-semi.h"
#include "exec/icount.h"
@@ -38,6 +41,52 @@
#include "pmp.h"
#include "qemu/plugin.h"
+/* Exceptions processing helpers */
+G_NORETURN void riscv_raise_exception(CPURISCVState *env,
+ RISCVException exception,
+ uintptr_t pc)
+{
+ CPUState *cs = env_cpu(env);
+
+ trace_riscv_exception(exception,
+ riscv_cpu_get_trap_name(exception, false),
+ env->pc);
+
+ cs->exception_index = exception;
+#ifdef CONFIG_TCG
+ cpu_loop_exit_restore(cs, pc);
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+target_ulong riscv_cpu_get_fflags(CPURISCVState *env)
+{
+ int soft = get_float_exception_flags(&env->fp_status);
+ target_ulong hard = 0;
+
+ hard |= (soft & float_flag_inexact) ? FPEXC_NX : 0;
+ hard |= (soft & float_flag_underflow) ? FPEXC_UF : 0;
+ hard |= (soft & float_flag_overflow) ? FPEXC_OF : 0;
+ hard |= (soft & float_flag_divbyzero) ? FPEXC_DZ : 0;
+ hard |= (soft & float_flag_invalid) ? FPEXC_NV : 0;
+
+ return hard;
+}
+
+void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong hard)
+{
+ int soft = 0;
+
+ soft |= (hard & FPEXC_NX) ? float_flag_inexact : 0;
+ soft |= (hard & FPEXC_UF) ? float_flag_underflow : 0;
+ soft |= (hard & FPEXC_OF) ? float_flag_overflow : 0;
+ soft |= (hard & FPEXC_DZ) ? float_flag_divbyzero : 0;
+ soft |= (hard & FPEXC_NV) ? float_flag_invalid : 0;
+
+ set_float_exception_flags(soft, &env->fp_status);
+}
+
int riscv_env_mmu_index(CPURISCVState *env, bool ifetch)
{
#ifdef CONFIG_USER_ONLY
@@ -1667,6 +1716,7 @@ static int get_physical_address(CPURISCVState *env,
hwaddr *physical,
return TRANSLATE_SUCCESS;
}
+#ifdef CONFIG_TCG
static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
MMUAccessType access_type, bool pmp_violation,
bool first_stage, bool two_stage,
@@ -1709,6 +1759,7 @@ static void raise_mmu_exception(CPURISCVState *env,
target_ulong address,
env->two_stage_lookup = two_stage;
env->two_stage_indirect_lookup = two_stage_indirect;
}
+#endif
hwaddr riscv_cpu_get_phys_addr_debug(CPUState *cs, vaddr addr)
{
@@ -1733,6 +1784,7 @@ hwaddr riscv_cpu_get_phys_addr_debug(CPUState *cs, vaddr
addr)
return phys_addr;
}
+#ifdef CONFIG_TCG
void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
vaddr addr, unsigned size,
MMUAccessType access_type,
@@ -1957,6 +2009,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int
size,
return true;
}
+#endif
static target_ulong riscv_transformed_insn(CPURISCVState *env,
target_ulong insn,
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 5514e0f455..04fa320ff8 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -2135,21 +2135,31 @@ static RISCVException read_misa(CPURISCVState *env, int
csrno,
static target_ulong get_next_pc(CPURISCVState *env, uintptr_t ra)
{
+ /* Outside of a running cpu, env contains the next pc. */
+ if (ra == 0) {
+ return env->pc;
+ }
+
+#ifdef CONFIG_TCG
uint64_t data[INSN_START_WORDS];
- /* Outside of a running cpu, env contains the next pc. */
- if (ra == 0 || !cpu_unwind_state_data(env_cpu(env), ra, data)) {
+ if (!cpu_unwind_state_data(env_cpu(env), ra, data)) {
return env->pc;
}
/* Within unwind data, [0] is pc and [1] is the opcode. */
return data[0] + insn_len(data[1]);
+#else
+ qemu_build_not_reached();
+#endif
}
static RISCVException write_misa(CPURISCVState *env, int csrno,
target_ulong val, uintptr_t ra)
{
+#ifdef CONFIG_TCG
RISCVCPU *cpu = env_archcpu(env);
+#endif
uint32_t orig_misa_ext = env->misa_ext;
Error *local_err = NULL;
@@ -2178,7 +2188,11 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
}
env->misa_ext = val;
+#ifdef CONFIG_TCG
riscv_cpu_validate_set_extensions(cpu, &local_err);
Maybe clearer to add as a stub?
+#else
+ qemu_build_not_reached();
+#endif
if (local_err != NULL) {
/* Rollback on validation error */
qemu_log_mask(LOG_GUEST_ERROR, "Unable to write MISA ext value "