target/riscv/cpu.c | 18 ++++++++++++++++++ target/riscv/cpu.h | 8 ++++++++ 2 files changed, 26 insertions(+)
From: Portia Stephens <portias@oss.tenstorrent.com>
CPU custom CSR implementations may require custom state information.
This adds support for a void struct to be added to CPUArchState to track
this state information.
Signed-off-by: Portia Stephens <portias@oss.tenstorrent.com>
---
target/riscv/cpu.c | 18 ++++++++++++++++++
target/riscv/cpu.h | 8 ++++++++
2 files changed, 26 insertions(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 862834b480..2e3acee76f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -819,6 +819,10 @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
if (kvm_enabled()) {
kvm_riscv_reset_vcpu(cpu);
}
+
+ if (env->custom_arch_state_reset) {
+ env->custom_arch_state_reset(env);
+ }
#endif
}
@@ -1167,6 +1171,12 @@ static void riscv_cpu_init(Object *obj)
if (mcc->def->custom_csrs) {
riscv_register_custom_csrs(cpu, mcc->def->custom_csrs);
}
+ if (mcc->def->custom_arch_state_init) {
+ mcc->def->custom_arch_state_init(&cpu->env);
+ }
+ if (mcc->def->custom_arch_state_reset) {
+ cpu->env.custom_arch_state_reset = mcc->def->custom_arch_state_reset;
+ }
#endif
accel_cpu_instance_init(CPU(obj));
@@ -2706,6 +2716,14 @@ static void riscv_cpu_class_base_init(ObjectClass *c, const void *data)
assert(!mcc->def->custom_csrs);
mcc->def->custom_csrs = def->custom_csrs;
}
+ if (def->custom_arch_state_init) {
+ assert(!mcc->def->custom_arch_state_init);
+ mcc->def->custom_arch_state_init = def->custom_arch_state_init;
+ }
+ if (def->custom_arch_state_reset) {
+ assert(!mcc->def->custom_arch_state_reset);
+ mcc->def->custom_arch_state_reset = def->custom_arch_state_reset;
+ }
}
if (!object_class_is_abstract(c)) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7d79c7a5a7..77b513c29a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -213,6 +213,9 @@ typedef struct PMUFixedCtrState {
uint64_t counter_virt_prev[2];
} PMUFixedCtrState;
+typedef void (*riscv_csr_custom_init_fn)(CPURISCVState *env);
+typedef void (*riscv_csr_custom_reset_fn)(CPURISCVState *env);
+
struct CPUArchState {
target_ulong gpr[32];
target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
@@ -509,6 +512,9 @@ struct CPUArchState {
uint64_t rnmip;
uint64_t rnmi_irqvec;
uint64_t rnmi_excpvec;
+
+ const void *custom_arch_state;
+ riscv_csr_custom_init_fn custom_arch_state_reset;
};
/*
@@ -561,6 +567,8 @@ typedef struct RISCVCPUDef {
RISCVCPUConfig cfg;
bool bare;
const RISCVCSR *custom_csrs;
+ riscv_csr_custom_init_fn custom_arch_state_init;
+ riscv_csr_custom_reset_fn custom_arch_state_reset;
} RISCVCPUDef;
/**
--
2.43.0
On Tue, 2026-05-26 at 20:17 +1000, stephensportia@gmail.com wrote:
> From: Portia Stephens <portias@oss.tenstorrent.com>
>
> CPU custom CSR implementations may require custom state information.
> This adds support for a void struct to be added to CPUArchState to
> track
> this state information.
Newline here please
> Signed-off-by: Portia Stephens <portias@oss.tenstorrent.com>
> ---
> target/riscv/cpu.c | 18 ++++++++++++++++++
> target/riscv/cpu.h | 8 ++++++++
> 2 files changed, 26 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 862834b480..2e3acee76f 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -819,6 +819,10 @@ static void riscv_cpu_reset_hold(Object *obj,
> ResetType type)
> if (kvm_enabled()) {
> kvm_riscv_reset_vcpu(cpu);
> }
> +
> + if (env->custom_arch_state_reset) {
> + env->custom_arch_state_reset(env);
> + }
> #endif
> }
>
> @@ -1167,6 +1171,12 @@ static void riscv_cpu_init(Object *obj)
> if (mcc->def->custom_csrs) {
> riscv_register_custom_csrs(cpu, mcc->def->custom_csrs);
> }
> + if (mcc->def->custom_arch_state_init) {
> + mcc->def->custom_arch_state_init(&cpu->env);
> + }
> + if (mcc->def->custom_arch_state_reset) {
> + cpu->env.custom_arch_state_reset = mcc->def-
> >custom_arch_state_reset;
> + }
> #endif
>
> accel_cpu_instance_init(CPU(obj));
> @@ -2706,6 +2716,14 @@ static void
> riscv_cpu_class_base_init(ObjectClass *c, const void *data)
> assert(!mcc->def->custom_csrs);
> mcc->def->custom_csrs = def->custom_csrs;
> }
> + if (def->custom_arch_state_init) {
> + assert(!mcc->def->custom_arch_state_init);
> + mcc->def->custom_arch_state_init = def-
> >custom_arch_state_init;
> + }
> + if (def->custom_arch_state_reset) {
> + assert(!mcc->def->custom_arch_state_reset);
> + mcc->def->custom_arch_state_reset = def-
> >custom_arch_state_reset;
> + }
> }
>
> if (!object_class_is_abstract(c)) {
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 7d79c7a5a7..77b513c29a 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -213,6 +213,9 @@ typedef struct PMUFixedCtrState {
> uint64_t counter_virt_prev[2];
> } PMUFixedCtrState;
>
> +typedef void (*riscv_csr_custom_init_fn)(CPURISCVState *env);
> +typedef void (*riscv_csr_custom_reset_fn)(CPURISCVState *env);
> +
> struct CPUArchState {
> target_ulong gpr[32];
> target_ulong gprh[32]; /* 64 top bits of the 128-bit registers
> */
> @@ -509,6 +512,9 @@ struct CPUArchState {
> uint64_t rnmip;
> uint64_t rnmi_irqvec;
> uint64_t rnmi_excpvec;
> +
> + const void *custom_arch_state;
> + riscv_csr_custom_init_fn custom_arch_state_reset;
Why are there two custom_arch_state_reset functions? One for init (this
one) and one for reset (the one in RISCVCPUDef)?
Why do we need a reset function here?
Can you add comments describing what these should be used for?
Alistair
> };
>
> /*
> @@ -561,6 +567,8 @@ typedef struct RISCVCPUDef {
> RISCVCPUConfig cfg;
> bool bare;
> const RISCVCSR *custom_csrs;
> + riscv_csr_custom_init_fn custom_arch_state_init;
> + riscv_csr_custom_reset_fn custom_arch_state_reset;
> } RISCVCPUDef;
>
> /**
© 2016 - 2026 Red Hat, Inc.