On 27/5/2026 3:58 PM, Philippe Mathieu-Daudé wrote:
Hi,

On 27/5/26 05:41, Alistair wrote:
On Wed, 27 May 2026, at 1:03 PM, [email protected] wrote:
From: Portia Stephens <[email protected]>

Custom vendor CSR implementations may require custom state information.
This adds a custom_arch-state struct to the CPUArchState. It also adds a
RISCVCPUDef function pointer for handling allocation and initialization
of the custom_arch_state as well as a reset function pointer for setting
the custom_arch_state fields to known values on reset.

Signed-off-by: Portia Stephens <[email protected]>
---
target/riscv/cpu.c | 15 +++++++++++++++
target/riscv/cpu.h |  7 +++++++
2 files changed, 22 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 862834b480..ca557d27b5 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 (mcc->def->custom_arch_state_reset) {
+        mcc->def->custom_arch_state_reset(env);

ResetType shouldn't be discarded IMO.

Are you referring to Alistair's comment about why do we need reset? Yes it is necessary to set the registers to a known state after a reset. A finalize function is probably also needed since init will allocate the struct.


+    }
#endif
}
@@ -1167,6 +1171,9 @@ 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);
+    }
#endif
      accel_cpu_instance_init(CPU(obj));
@@ -2706,6 +2713,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..8132c65012 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,8 @@ struct CPUArchState {
      uint64_t rnmip;
      uint64_t rnmi_irqvec;
      uint64_t rnmi_excpvec;
+
+    const void *custom_arch_state;
};
/*
@@ -561,6 +566,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;

Why do we need an init and a reset? I assume init is to allocate the stuct, but that should probably be commented here.

How do you expect these to be set? Do you have an example?

I don't see the point of upstreaming this patch without concrete
example. So far it is maintenance burden without any value.

Okay.



Alistair

} RISCVCPUDef;
/**
--
2.43.0







Reply via email to