qemu-riscv
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw(


From: Ruinland ChuanTzu Tsai
Subject: Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
Date: Fri, 22 Oct 2021 16:34:28 +0800
User-agent: Mutt/2.1.3 (987dde4c) (2021-09-10)

On Thu, Oct 21, 2021 at 05:08:09PM -0700, Richard Henderson wrote:
> On 10/21/21 8:09 AM, Ruinland Chuan-Tzu Tsai wrote:
> > riscv_csrrw() will be called by CSR handling helpers, which is the
> > most suitable place for checking wheter a custom CSR is being accessed.
> > 
> > If we're touching a custom CSR, invoke the registered handlers.
> > 
> > Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> > ---
> >   target/riscv/cpu.c             | 19 +++++++++++++++++
> >   target/riscv/cpu.h             | 13 +++++++++++-
> >   target/riscv/csr.c             | 38 +++++++++++++++++++++++++++-------
> >   target/riscv/custom_csr_defs.h |  7 +++++++
> >   4 files changed, 68 insertions(+), 9 deletions(-)
> >   create mode 100644 target/riscv/custom_csr_defs.h
> > 
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 0c93b7edd7..a72fd32f01 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -34,6 +34,9 @@
> >   static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
> > +GHashTable *custom_csr_map = NULL;
> 
> Leftover from a previous revision?

By default there's no custom_csr_map (pointing to NULL) and thus only the
custom CSR equipped CPU models will need to initialize that. Standard CPU will
pass the check of custom_csr_map in riscv_csrrw() by default.

> 
> > +#include "custom_csr_defs.h"
> 
> I think that the few declarations that are required can just go in 
> internals.h.

Wilco.

> 
> > +
> >   const char * const riscv_int_regnames[] = {
> >     "x0/zero", "x1/ra",  "x2/sp",  "x3/gp",  "x4/tp",  "x5/t0",   "x6/t1",
> >     "x7/t2",   "x8/s0",  "x9/s1",  "x10/a0", "x11/a1", "x12/a2",  "x13/a3",
> > @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, 
> > target_ulong resetvec)
> >   #endif
> >   }
> > +static void setup_custom_csr(CPURISCVState *env,
> > +                             riscv_custom_csr_operations csr_map_struct[])
> 
> Why is this static?  Surely it needs to be called from csr_andes.c, etc?
> Oh, I see that in the next patch you call this directly from ax25_cpu_init.
> 
> I think the split of declarations is less than ideal.  See below.
> 
> > +{
> > +    int i;
> > +    env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> > +    for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
> 
> Having a hard maximum seems a mistake.  You should pass in the array size...
> 
> > +        if (csr_map_struct[i].csrno != 0) {
> > +            g_hash_table_insert(env->custom_csr_map,
> > +                GINT_TO_POINTER(csr_map_struct[i].csrno),
> > +                &csr_map_struct[i].csr_opset);
> > +        } else {
> > +            break;
> > +        }
> 
> ... which would also allow you to remove the terminator in the data, and the 
> check here.

Wilco.

> 
> > @@ -245,6 +245,11 @@ struct CPURISCVState {
> >       /* Fields from here on are preserved across CPU reset. */
> >       QEMUTimer *timer; /* Internal timer */
> > +
> > +    /* Custom CSR opset table per hart */
> > +    GHashTable *custom_csr_map;
> 
> I think placing this in the CPURISCVState is incorrect.  A much better place
> would be on the RISCVCPUClass, so that there is exactly one copy of this per
> cpu type, i.e. all A25/AX25 cpus would share the same table.
> 
> You would of course need to hook class_init, which the current definition of
> DEFINE_CPU does not allow.  But that's easy to fix.
> 
> > +    /* Custom CSR value holder per hart */
> > +    void *custom_csr_val;
> >   };
> 
> Value singular?  Anyhow, I think that it's a mistake trying to hide the
> value structure in another file.  It complicates allocation of the
> CPURISCVState, and you have no mechanism by which to migrate the csr values.

What I'm trying to do here is to provide a hook for CSR value storage and let
it being set during CPU initilization. We have heterogeneous harts which
have different sets of CSRs.

> 
> I think you should simply place your structure here in CPURISCVState.
> 
> > +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> > +{
> > +    gpointer ret;
> > +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> > +    return ret;
> > +}
> 
> Fix the return type; the csr is not gpointer.
> It would be better to put the map not null test here.
> 
> I think it would be even better to name this find_csr,
> and include the normal index of csr_ops[] if the map
> test fails.

Wilco.

> 
> > @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int 
> > csrno,
> >           return RISCV_EXCP_ILLEGAL_INST;
> >       }
> > +    /* try to handle_custom_csr */
> > +    if (unlikely(env->custom_csr_map != NULL)) {
> > +        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> > +            find_custom_csr(env, csrno);
> > +        if (custom_csr_opset != NULL) {
> > +            csr_op = custom_csr_opset;
> > +            } else {
> > +            csr_op = &csr_ops[csrno];
> > +            }
> > +        } else {
> > +        csr_op = &csr_ops[csrno];
> > +        }
> 
> As Alistair noted, run checkpatch.pl to find all of these indentation errors.
> 
> That said, a better structure here would be
> 
>     csr_op = find_csr(env, csrno);
>     if (csr_op == NULL) {
>         return RISCV_EXCP_ILLEGAL_INST;
>     }

Thanks for the tips. Wilco.
> 
> 
> r~

Cordially yours,
Ruinland



reply via email to

[Prev in Thread] Current Thread [Next in Thread]