[PATCH] target/riscv: Add support for a custom CPU arch state

stephensportia@gmail.com posted 1 patch 4 days, 6 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260526101732.54144-1-stephensportia@gmail.com
Maintainers: Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Chao Liu <chao.liu.zevorn@gmail.com>
There is a newer version of this series
target/riscv/cpu.c | 18 ++++++++++++++++++
target/riscv/cpu.h |  8 ++++++++
2 files changed, 26 insertions(+)
[PATCH] target/riscv: Add support for a custom CPU arch state
Posted by stephensportia@gmail.com 4 days, 6 hours ago
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
Re: [PATCH] target/riscv: Add support for a custom CPU arch state
Posted by Alistair Francis 3 days, 15 hours ago
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;
>  
>  /**