Re: [PATCH v2] riscv: thead: Add th.sxstatus CSR emulation

2024-04-04 Thread LIU Zhiwei
riscv_set_csr_ops(csrno, csr_ops);
+}
+}


Otherwise,

Reviewed-by: LIU Zhiwei 

Zhiwei




Re: [PATCH v2] target/riscv: Fix the element agnostic function problem

2024-03-20 Thread LIU Zhiwei



On 2024/3/21 11:58, Huang Tao wrote:

In RVV and vcrypto instructions, the masked and tail elements are set to 1s
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
agnostic policy.

However, this function can't deal the big endian situation. This patch fixes
the problem by adding handling of such case.

Signed-off-by: Huang Tao 
Suggested-by: Richard Henderson 
---
Changes in v2:
- Keep the api of vext_set_elems_1s
- Reduce the number of patches.
---
  target/riscv/vector_internals.c | 22 ++
  1 file changed, 22 insertions(+)

diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
index 12f5964fbb..3e45b9b4a7 100644
--- a/target/riscv/vector_internals.c
+++ b/target/riscv/vector_internals.c
@@ -30,6 +30,28 @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, 
uint32_t cnt,
  if (tot - cnt == 0) {
  return ;
  }
+
+#if HOST_BIG_ENDIAN
+/*
+ * Deal the situation when the elements are insdie
+ * only one uint64 block including setting the
+ * masked-off element.
+ */
+if ((tot - 1) ^ cnt < 8) {
+memset(base + H1(tot - 1), -1, tot - cnt);
+return;
+}
+/*
+ * Otherwise, at least cross two uint64_t blocks.
+ * Set first unaligned block.
+ */
+if (cnt % 8 != 0) {
+uint32_t j = ROUND_UP(cnt, 8);
+memset(base + H1(j - 1), -1, j - cnt);
+cnt = j;
+}
+/* Set other 64bit aligend blocks */
+#endif


Reviewed-by: LIU Zhiwei 

Zhiwei


  memset(base + cnt, -1, tot - cnt);
  }
  




Re: [PATCH for 9.0 v15 04/10] target/riscv: always clear vstart in whole vec move insns

2024-03-19 Thread LIU Zhiwei



On 2024/3/15 1:56, Daniel Henrique Barboza wrote:

These insns have 2 paths: we'll either have vstart already cleared if
vstart_eq_zero or we'll do a brcond to check if vstart >= maxsz to call
the 'vmvr_v' helper. The helper will clear vstart if it executes until
the end, or if vstart >= vl.

For starters, the check itself is wrong: we're checking vstart >= maxsz,
when in fact we should use vstart in bytes, or 'startb' like 'vmvr_v' is
calling, to do the comparison. But even after fixing the comparison we'll
still need to clear vstart in the end, which isn't happening too.

We want to make the helpers responsible to manage vstart, including
these corner cases, precisely to avoid these situations:

- remove the wrong vstart >= maxsz cond from the translation;
- add a 'startb >= maxsz' cond in 'vmvr_v', and clear vstart if that
   happens.

This way we're now sure that vstart is being cleared in the end of the
execution, regardless of the path taken.

Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR")
Signed-off-by: Daniel Henrique Barboza 


Reviewed-by: LIU Zhiwei 

Zhiwei


---
  target/riscv/insn_trans/trans_rvv.c.inc | 3 ---
  target/riscv/vector_helper.c| 5 +
  2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 8c16a9f5b3..52c26a7834 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3664,12 +3664,9 @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * 
a)   \
   vreg_ofs(s, a->rs2), maxsz, maxsz);\
  mark_vs_dirty(s);   \
  } else {\
-TCGLabel *over = gen_new_label();   \
-tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, maxsz, over);  \
  tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \
 tcg_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \
  mark_vs_dirty(s);   \
-gen_set_label(over);\
  }   \
  return true;\
  }   \
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 34ac4aa808..bcc553c0e2 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -5075,6 +5075,11 @@ void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState 
*env, uint32_t desc)
  uint32_t startb = env->vstart * sewb;
  uint32_t i = startb;
  
+if (startb >= maxsz) {

+env->vstart = 0;
+return;
+}
+
  if (HOST_BIG_ENDIAN && i % 8 != 0) {
  uint32_t j = ROUND_UP(i, 8);
  memcpy((uint8_t *)vd + H1(j - 1),




Re: [PATCH for 9.0 v15 03/10] target/riscv/vector_helper.c: fix 'vmvr_v' memcpy endianess

2024-03-19 Thread LIU Zhiwei



On 2024/3/15 1:56, Daniel Henrique Barboza wrote:

vmvr_v isn't handling the case where the host might be big endian and
the bytes to be copied aren't sequential.

Suggested-by: Richard Henderson 
Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR")
Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/vector_helper.c | 10 +-
  1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index ca79571ae2..34ac4aa808 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -5075,9 +5075,17 @@ void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState 
*env, uint32_t desc)
  uint32_t startb = env->vstart * sewb;
  uint32_t i = startb;
  
+if (HOST_BIG_ENDIAN && i % 8 != 0) {

+uint32_t j = ROUND_UP(i, 8);
+memcpy((uint8_t *)vd + H1(j - 1),
+   (uint8_t *)vs2 + H1(j - 1),
+   j - i);
+i = j;
+}
+
  memcpy((uint8_t *)vd + H1(i),
 (uint8_t *)vs2 + H1(i),
-   maxsz - startb);
+   maxsz - i);


Reviewed-by: LIU Zhiwei 

Zhiwei

  
  env->vstart = 0;

  }




Re: [PATCH for 9.0 v15 02/10] trans_rvv.c.inc: set vstart = 0 in int scalar move insns

2024-03-18 Thread LIU Zhiwei



On 2024/3/15 1:56, Daniel Henrique Barboza wrote:

trans_vmv_x_s, trans_vmv_s_x, trans_vfmv_f_s and trans_vfmv_s_f aren't
setting vstart = 0 after execution. This is usually done by a helper in
vector_helper.c but these functions don't use helpers.

We'll set vstart after any potential 'over' brconds, and that will also
mandate a mark_vs_dirty() too.

Fixes: dedc53cbc9 ("target/riscv: rvv-1.0: integer scalar move instructions")
Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Richard Henderson 


Reviewd-by: LIU Zhiwei 

Zhiwei


---
  target/riscv/insn_trans/trans_rvv.c.inc | 10 --
  1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index e42728990e..8c16a9f5b3 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3373,6 +3373,8 @@ static bool trans_vmv_x_s(DisasContext *s, arg_vmv_x_s *a)
  vec_element_loadi(s, t1, a->rs2, 0, true);
  tcg_gen_trunc_i64_tl(dest, t1);
  gen_set_gpr(s, a->rd, dest);
+tcg_gen_movi_tl(cpu_vstart, 0);
+mark_vs_dirty(s);
  return true;
  }
  return false;
@@ -3399,8 +3401,9 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
  s1 = get_gpr(s, a->rs1, EXT_NONE);
  tcg_gen_ext_tl_i64(t1, s1);
  vec_element_storei(s, a->rd, 0, t1);
-mark_vs_dirty(s);
  gen_set_label(over);
+tcg_gen_movi_tl(cpu_vstart, 0);
+mark_vs_dirty(s);
  return true;
  }
  return false;
@@ -3427,6 +3430,8 @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s 
*a)
  }
  
  mark_fs_dirty(s);

+tcg_gen_movi_tl(cpu_vstart, 0);
+mark_vs_dirty(s);
  return true;
  }
  return false;
@@ -3452,8 +3457,9 @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f 
*a)
  do_nanbox(s, t1, cpu_fpr[a->rs1]);
  
  vec_element_storei(s, a->rd, 0, t1);

-mark_vs_dirty(s);
  gen_set_label(over);
+tcg_gen_movi_tl(cpu_vstart, 0);
+mark_vs_dirty(s);
  return true;
  }
  return false;




Re: [PATCH for 9.0 v15 01/10] target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX()

2024-03-18 Thread LIU Zhiwei



On 2024/3/15 1:56, Daniel Henrique Barboza wrote:

The helper isn't setting env->vstart = 0 after its execution, as it is
expected from every vector instruction that completes successfully.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 


Reviewed-by: LIU Zhiwei 

Zhiwei


---
  target/riscv/vector_helper.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index fe56c007d5..ca79571ae2 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4781,6 +4781,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2, \
  } \
  *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - offset));  \
  } \
+env->vstart = 0;  \
  /* set tail elements to 1s */ \
  vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);  \
  }




Re: [PATCH v2] target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR

2024-03-11 Thread LIU Zhiwei



On 2024/3/11 11:08, Yu-Ming Chang wrote:

Both CSRRS and CSRRC always read the addressed CSR and cause any read side
effects regardless of rs1 and rd fields. Note that if rs1 specifies a register
holding a zero value other than x0, the instruction will still attempt to write
the unmodified value back to the CSR and will cause any attendant side effects.

So if CSRRS or CSRRC tries to write a read-only CSR with rs1 which specifies
a register holding a zero value, an illegal instruction exception should be
raised.

Signed-off-by: Yu-Ming Chang 
---
This incorporated the comments from Richard. Thank you.

  target/riscv/cpu.h   |  2 ++
  target/riscv/csr.c   | 17 ++---
  target/riscv/op_helper.c |  2 +-
  3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5d291a7092..452841ae2f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -710,6 +710,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
  void riscv_cpu_update_mask(CPURISCVState *env);
  bool riscv_cpu_is_32bit(RISCVCPU *cpu);
  
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,

+  target_ulong *ret_value);
  RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
 target_ulong *ret_value,
 target_ulong new_value, target_ulong write_mask);
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d4e8ac13b9..0d14ba2ba5 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -4306,7 +4306,7 @@ static RISCVException rmw_seed(CPURISCVState *env, int 
csrno,
  
  static inline RISCVException riscv_csrrw_check(CPURISCVState *env,

 int csrno,
-   bool write_mask)
+   bool write)
  {
  /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
  bool read_only = get_field(csrno, 0xC00) == 3;
@@ -4328,7 +4328,7 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
  }
  
  /* read / write check */

-if (write_mask && read_only) {
+if (write && read_only) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
@@ -4415,11 +4415,22 @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,

  return RISCV_EXCP_NONE;
  }
  
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,

+   target_ulong *ret_value)
+{
+RISCVException ret = riscv_csrrw_check(env, csrno, false);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
+return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
+}
+
  RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
 target_ulong *ret_value,
 target_ulong new_value, target_ulong write_mask)
  {
-RISCVException ret = riscv_csrrw_check(env, csrno, write_mask);
+RISCVException ret = riscv_csrrw_check(env, csrno, true);
  if (ret != RISCV_EXCP_NONE) {
  return ret;
  }
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index f414aaebdb..f3aa705be8 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -51,7 +51,7 @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
  }
  
  target_ulong val = 0;

-RISCVException ret = riscv_csrrw(env, csr, , 0, 0);
+RISCVException ret = riscv_csrr(env, csr, );
  
  if (ret != RISCV_EXCP_NONE) {

  riscv_raise_exception(env, ret, GETPC());


Hi Yu-Ming,

The 128-bit CSR operations have the similar errors. Could you solve the 
similar bug in this patch set?


Otherwise,

Reviewed-by: LIU Zhiwei 

Thanks,
Zhiwei




Re: [PATCH v12 4/7] target/riscv: remove 'over' brconds from vector trans

2024-03-11 Thread LIU Zhiwei



On 2024/3/12 2:08, Daniel Henrique Barboza wrote:

The previous patch added an early vstart >= vl exit in all vector
helpers, most of them using the VSTART_CHECK_EARLY_EXIT() macro,
and now we're left with a lot of 'brcond' that has not use. The
pattern goes like this:

 VSTART_CHECK_EARLY_EXIT(env);
 (...)
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 (...)
 gen_set_label(over);
 return true;

The early exit makes the 'brcond' unneeded since it's already granted that
vstart < vl. Remove all 'over' conditionals from the vector helpers.

Note that not all insns uses helpers, and for those cases the 'brcond'
jump is the only way to filter vstart >= vl. This is the case of
trans_vmv_s_x() and trans_vfmv_s_f(). We won't remove the 'brcond'
conditionals from them.

While we're at it, remove the (vl == 0) brconds from trans_rvbf16.c.inc
too since they're unneeded.

Suggested-by: Richard Henderson 
Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
  target/riscv/insn_trans/trans_rvbf16.c.inc |  12 ---
  target/riscv/insn_trans/trans_rvv.c.inc| 108 -
  target/riscv/insn_trans/trans_rvvk.c.inc   |  18 
  3 files changed, 138 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvbf16.c.inc 
b/target/riscv/insn_trans/trans_rvbf16.c.inc
index 8ee99df3f3..a842e76a6b 100644
--- a/target/riscv/insn_trans/trans_rvbf16.c.inc
+++ b/target/riscv/insn_trans/trans_rvbf16.c.inc
@@ -71,11 +71,8 @@ static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, 
arg_vfncvtbf16_f_f_w *a)
  
  if (opfv_narrow_check(ctx, a) && (ctx->sew == MO_16)) {

  uint32_t data = 0;
-TCGLabel *over = gen_new_label();
  
  gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);

-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
-tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
  
  data = FIELD_DP32(data, VDATA, VM, a->vm);

  data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
@@ -87,7 +84,6 @@ static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, 
arg_vfncvtbf16_f_f_w *a)
 ctx->cfg_ptr->vlenb, data,
 gen_helper_vfncvtbf16_f_f_w);
  mark_vs_dirty(ctx);
-gen_set_label(over);
  return true;
  }
  return false;
@@ -100,11 +96,8 @@ static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, 
arg_vfwcvtbf16_f_f_v *a)
  
  if (opfv_widen_check(ctx, a) && (ctx->sew == MO_16)) {

  uint32_t data = 0;
-TCGLabel *over = gen_new_label();
  
  gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);

-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
-tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
  
  data = FIELD_DP32(data, VDATA, VM, a->vm);

  data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
@@ -116,7 +109,6 @@ static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, 
arg_vfwcvtbf16_f_f_v *a)
 ctx->cfg_ptr->vlenb, data,
 gen_helper_vfwcvtbf16_f_f_v);
  mark_vs_dirty(ctx);
-gen_set_label(over);
  return true;
  }
  return false;
@@ -130,11 +122,8 @@ static bool trans_vfwmaccbf16_vv(DisasContext *ctx, 
arg_vfwmaccbf16_vv *a)
  if (require_rvv(ctx) && vext_check_isa_ill(ctx) && (ctx->sew == MO_16) &&
  vext_check_dss(ctx, a->rd, a->rs1, a->rs2, a->vm)) {
  uint32_t data = 0;
-TCGLabel *over = gen_new_label();
  
  gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);

-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
-tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
  
  data = FIELD_DP32(data, VDATA, VM, a->vm);

  data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
@@ -147,7 +136,6 @@ static bool trans_vfwmaccbf16_vv(DisasContext *ctx, 
arg_vfwmaccbf16_vv *a)
 ctx->cfg_ptr->vlenb, data,
 gen_helper_vfwmaccbf16_vv);
  mark_vs_dirty(ctx);
-gen_set_label(over);
  return true;
  }
  return false;
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 8c16a9f5b3..4c1a064cf6 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -616,9 +616,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, 
uint32_t data,
  TCGv base;
  TCGv_i32 desc;
  
-TCGLabel *over = gen_new_label();

-tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
-
  dest = tcg_temp_new_ptr();
  mask = tcg_temp_new_ptr();
  base = get_gpr(s, rs1, EXT_NONE);
@@ -660,7 +657,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, 
uint32_t data,
  tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
  }
  
-gen_set_label(over);

  return true;
  }
  
@@ -802,9 +798,6 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t 

Re: [PATCH v9 04/10] target/riscv/vector_helper.c: update tail with vext_set_tail_elems_1s()

2024-03-10 Thread LIU Zhiwei



On 2024/3/10 4:43, Daniel Henrique Barboza wrote:

Change all code that updates tail elems to use vext_set_tail_elems_1s()
instead of vext_set_elems_1s().


Hi Daniel,

Notice vext_set_tail_elems_1s will use NF field, which is zero for most 
vector instructions. Thus it will do nothing.
I think you need encode the  right NF value(1) into desc for them if you 
want to do this replacement.


Thanks,
Zhiwei



Setting 'env->vstart=0' needs to be the very last thing a helper does
because env->vstart is being checked by vext_set_tail_elems_1s().

A side effect of this change is that a lot of 'vta' local variables got
unused. The reason is that 'vta' was being fetched to be used with
vext_set_elems_1s() but vext_set_tail_elems_1s() doesn't use it - 'vta' is
retrieve inside the helper using 'desc'.

Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/vector_helper.c | 130 ++-
  1 file changed, 52 insertions(+), 78 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 86b990ce03..b174ddeae8 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -913,7 +913,6 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, 
  \
  uint32_t esz = sizeof(ETYPE); \
  uint32_t total_elems =\
  vext_get_total_elems(env, desc, esz); \
-uint32_t vta = vext_vta(desc);\
  uint32_t i;   \
\
  for (i = env->vstart; i < vl; i++) {  \
@@ -923,9 +922,9 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, 
  \
\
  *((ETYPE *)vd + H(i)) = DO_OP(s2, s1, carry); \
  } \
-env->vstart = 0;  \
  /* set tail elements to 1s */ \
-vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);  \
+vext_set_tail_elems_1s(env, vd, desc, esz, total_elems);  \
+env->vstart = 0;  \
  }
  
  GEN_VEXT_VADC_VVM(vadc_vvm_b, uint8_t,  H1, DO_VADC)

@@ -945,7 +944,6 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void 
*vs2,\
  uint32_t vl = env->vl;   \
  uint32_t esz = sizeof(ETYPE);\
  uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
-uint32_t vta = vext_vta(desc);   \
  uint32_t i;  \
   \
  for (i = env->vstart; i < vl; i++) { \
@@ -954,9 +952,9 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void 
*vs2,\
   \
  *((ETYPE *)vd + H(i)) = DO_OP(s2, (ETYPE)(target_long)s1, carry);\
  }\
-env->vstart = 0; \
  /* set tail elements to 1s */\
-vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz); \
+vext_set_tail_elems_1s(env, vd, desc, esz, total_elems); \
+env->vstart = 0; \
  }
  
  GEN_VEXT_VADC_VXM(vadc_vxm_b, uint8_t,  H1, DO_VADC)

@@ -1113,7 +,6 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,  
\
  uint32_t vl = env->vl;\
  uint32_t esz = sizeof(TS1);   \
  uint32_t total_elems = vext_get_total_elems(env, desc, esz);  \
-uint32_t vta = vext_vta(desc);\
  uint32_t vma = vext_vma(desc);\
  uint32_t i;   \
\
@@ -1127,9 +1124,9 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,  
\
  TS2 s2 = *((TS2 *)vs2 + HS2(i));  \
  *((TS1 *)vd + HS1(i)) = OP(s2, s1 & MASK);\
  } \
-env->vstart = 0;  \
  /* set tail elements to 1s */ \
-vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);  \
+

Re: [PATCH v7 3/9] target/riscv: remove 'over' brconds from vector trans

2024-03-07 Thread LIU Zhiwei

Hi Daniel and Alistair,

Hope it is not too late. I think there are two bugs in this patch.

1) The first is for instruction vfmv.s.f.  vfmv.s.f doesn't use helper 
function. If we remove the over check, it will set the first element of 
destination vector register, which is against the specification. 
According to the riscv-v-specification, 16.2. Floating-Point Scalar Move 
Instructions,


"If vstart ≥ vl, no operation is performed and the destination register is not 
updated".

2) The second is for vector instruction with helper functions. we should 
not change any elements including the tail elements when vstart >=vl. 
But this patch break this behavior. According to the 
riscv-v-specification,  5.4. Prestart, Active, Inactive, Body, and Tail 
Element Denitions,


"When vstart ≥ vl, there are no body elements, and no elements are updated in 
any destination vector register group,
including that no tail elements are updated with agnostic values."

I will review this patch set in more details later.

Thanks,
Zhiwei

On 2024/3/7 1:19, Daniel Henrique Barboza wrote:

Most of the vector translations has this following pattern at the start:

 TCGLabel *over = gen_new_label();
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);

And then right at the end:

  gen_set_label(over);
  return true;

This means that if vstart >= vl we'll not set vstart = 0 at the end of
the insns - this is done inside the helper that is being skipped.  The
reason why this pattern hasn't been a bigger problem is because the
conditional vstart >= vl is very rare.

Checking all the helpers in vector_helper.c we see all of them with a
pattern like this:

 for (i = env->vstart; i < vl; i++) {
 (...)
 }
 env->vstart = 0;

Thus they can handle vstart >= vl case gracefully, with the benefit of
setting env->vstart = 0 during the process.

Remove all 'over' conditionals and let the helper set env->vstart = 0
every time.

While we're at it, remove the (vl == 0) brconds from trans_rvbf16.c.inc
too since they're unneeded.

Suggested-by: Richard Henderson
Signed-off-by: Daniel Henrique Barboza
Reviewed-by: Richard Henderson
Reviewed-by: Alistair Francis
---
  target/riscv/insn_trans/trans_rvbf16.c.inc |  12 ---
  target/riscv/insn_trans/trans_rvv.c.inc| 117 -
  target/riscv/insn_trans/trans_rvvk.c.inc   |  18 
  3 files changed, 147 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvbf16.c.inc 
b/target/riscv/insn_trans/trans_rvbf16.c.inc
index 8ee99df3f3..a842e76a6b 100644
--- a/target/riscv/insn_trans/trans_rvbf16.c.inc
+++ b/target/riscv/insn_trans/trans_rvbf16.c.inc
@@ -71,11 +71,8 @@ static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, 
arg_vfncvtbf16_f_f_w *a)
  
  if (opfv_narrow_check(ctx, a) && (ctx->sew == MO_16)) {

  uint32_t data = 0;
-TCGLabel *over = gen_new_label();
  
  gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);

-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
-tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
  
  data = FIELD_DP32(data, VDATA, VM, a->vm);

  data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
@@ -87,7 +84,6 @@ static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, 
arg_vfncvtbf16_f_f_w *a)
 ctx->cfg_ptr->vlenb, data,
 gen_helper_vfncvtbf16_f_f_w);
  mark_vs_dirty(ctx);
-gen_set_label(over);
  return true;
  }
  return false;
@@ -100,11 +96,8 @@ static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, 
arg_vfwcvtbf16_f_f_v *a)
  
  if (opfv_widen_check(ctx, a) && (ctx->sew == MO_16)) {

  uint32_t data = 0;
-TCGLabel *over = gen_new_label();
  
  gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);

-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
-tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
  
  data = FIELD_DP32(data, VDATA, VM, a->vm);

  data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
@@ -116,7 +109,6 @@ static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, 
arg_vfwcvtbf16_f_f_v *a)
 ctx->cfg_ptr->vlenb, data,
 gen_helper_vfwcvtbf16_f_f_v);
  mark_vs_dirty(ctx);
-gen_set_label(over);
  return true;
  }
  return false;
@@ -130,11 +122,8 @@ static bool trans_vfwmaccbf16_vv(DisasContext *ctx, 
arg_vfwmaccbf16_vv *a)
  if (require_rvv(ctx) && vext_check_isa_ill(ctx) && (ctx->sew == MO_16) &&
  vext_check_dss(ctx, a->rd, a->rs1, a->rs2, a->vm)) {
  uint32_t data = 0;
-TCGLabel *over = gen_new_label();
  
  gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);

-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
-tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
  
  data = FIELD_DP32(data, VDATA, VM, a->vm);

  data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
@@ -147,7 +136,6 

Re: [PATCH v5 1/5] target/riscv: Fix the predicate functions for mhpmeventhX CSRs

2024-03-04 Thread LIU Zhiwei



On 2024/2/29 2:51, Atish Patra wrote:

mhpmeventhX CSRs are available for RV32. The predicate function
should check that first before checking sscofpmf extension.

Fixes: 14664483457b ("target/riscv: Add sscofpmf extension support")
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 


Reviewed-by: LIU Zhiwei 

Zhiwei


Signed-off-by: Atish Patra 
---
  target/riscv/csr.c | 67 ++
  1 file changed, 38 insertions(+), 29 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d4e8ac13b90c..a3d979c4c72c 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -227,6 +227,15 @@ static RISCVException sscofpmf(CPURISCVState *env, int 
csrno)
  return RISCV_EXCP_NONE;
  }
  
+static RISCVException sscofpmf_32(CPURISCVState *env, int csrno)

+{
+if (riscv_cpu_mxl(env) != MXL_RV32) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+return sscofpmf(env, csrno);
+}
+
  static RISCVException any(CPURISCVState *env, int csrno)
  {
  return RISCV_EXCP_NONE;
@@ -5035,91 +5044,91 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
  [CSR_MHPMEVENT31]= { "mhpmevent31",any,read_mhpmevent,
   write_mhpmevent   },
  
-[CSR_MHPMEVENT3H]= { "mhpmevent3h",sscofpmf,  read_mhpmeventh,

+[CSR_MHPMEVENT3H]= { "mhpmevent3h",sscofpmf_32,  read_mhpmeventh,
   write_mhpmeventh,
   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_MHPMEVENT4H]= { "mhpmevent4h",sscofpmf,  read_mhpmeventh,
+[CSR_MHPMEVENT4H]= { "mhpmevent4h",sscofpmf_32,  read_mhpmeventh,
   write_mhpmeventh,
   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_MHPMEVENT5H]= { "mhpmevent5h",sscofpmf,  read_mhpmeventh,
+[CSR_MHPMEVENT5H]= { "mhpmevent5h",sscofpmf_32,  read_mhpmeventh,
   write_mhpmeventh,
   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_MHPMEVENT6H]= { "mhpmevent6h",sscofpmf,  read_mhpmeventh,
+[CSR_MHPMEVENT6H]= { "mhpmevent6h",sscofpmf_32,  read_mhpmeventh,
   write_mhpmeventh,
   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_MHPMEVENT7H]= { "mhpmevent7h",sscofpmf,  read_mhpmeventh,
+[CSR_MHPMEVENT7H]= { "mhpmevent7h",sscofpmf_32,  read_mhpmeventh,
   write_mhpmeventh,
   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_MHPMEVENT8H]= { "mhpmevent8h",sscofpmf,  read_mhpmeventh,
+[CSR_MHPMEVENT8H]= { "mhpmevent8h",sscofpmf_32,  read_mhpmeventh,
   write_mhpmeventh,
   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_MHPMEVENT9H]= { "mhpmevent9h",sscofpmf,  read_mhpmeventh,
+[CSR_MHPMEVENT9H]= { "mhpmevent9h",sscofpmf_32,  read_mhpmeventh,
   write_mhpmeventh,
   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_MHPMEVENT10H]   = { "mhpmevent10h",sscofpmf,  read_mhpmeventh,
+[CSR_MHPMEVENT10H]   = { "mhpmevent10h",sscofpmf_32,  read_mhpmeventh,
   write_mhpmeventh,
   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_MHPMEVENT11H]   = { "mhpmevent11h",sscofpmf,  read_mhpmeventh,
+[CSR_MHPMEVENT11H]   = { "mhpmevent11h",sscofpmf_32,  read_mhpmeventh,
   write_mhpmeventh,
   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_MHPMEVENT12H]   = { "mhpmevent12h",sscofpmf,  read_mhpmeventh,
+[CSR_MHPMEVENT12H]   = { "mhpmevent12h",sscofpmf_32,  read_mhpmeventh,
   write_mhpmeventh,
   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_MHPMEVENT13H]   = { "mhpmevent13h",sscofpmf,  read_mhpmeventh,
+[CSR_MHPMEVENT13H]   = { "mhpmevent13h",sscofpmf_32,  read_mhpmeventh,
   write_mhpmeventh,
   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_MHPMEVENT14H]   = { "mhpmevent14h",sscofpmf,  read_mhpmeventh,
+[CSR_MHPMEVENT14H]   = { "mhpmevent14h",sscofpmf_32,  read_mhpmeventh,
   write_mhpmeventh,
   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_MHPMEVENT15H]   = { "mhpmevent15h",sscofpm

Re: [PATCH v5 2/5] target/riscv: Add cycle & instret privilege mode filtering properties

2024-03-04 Thread LIU Zhiwei



On 2024/2/29 2:51, Atish Patra wrote:

From: Kaiwen Xue 

This adds the properties for ISA extension smcntrpmf. Patches
implementing it will follow.

Signed-off-by: Atish Patra 
Signed-off-by: Kaiwen Xue 
---
  target/riscv/cpu.c | 2 ++
  target/riscv/cpu_cfg.h | 1 +
  2 files changed, 3 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1b8d001d237f..f9d3c80597fc 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -169,6 +169,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
  ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
  ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
  ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
+ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
  ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
  ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
  ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
@@ -1447,6 +1448,7 @@ const char *riscv_get_misa_ext_description(uint32_t bit)
  const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
  /* Defaults for standard extensions */
  MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
+MULTI_EXT_CFG_BOOL("smcntrpmf", ext_smcntrpmf, false),
  MULTI_EXT_CFG_BOOL("zifencei", ext_zifencei, true),
  MULTI_EXT_CFG_BOOL("zicsr", ext_zicsr, true),
  MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),


We should not add the configure option for users before the feature has 
been implemented for bitsect reasons.


Thanks,
Zhiwei


diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 833bf5821708..0828841445c5 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -73,6 +73,7 @@ struct RISCVCPUConfig {
  bool ext_zihpm;
  bool ext_smstateen;
  bool ext_sstc;
+bool ext_smcntrpmf;
  bool ext_svadu;
  bool ext_svinval;
  bool ext_svnapot;




Re: [PATCH v5 5/5] target/riscv: Implement privilege mode filtering for cycle/instret

2024-03-04 Thread LIU Zhiwei



On 2024/2/29 2:51, Atish Patra wrote:

Privilege mode filtering can also be emulated for cycle/instret by
tracking host_ticks/icount during each privilege mode switch. This
patch implements that for both cycle/instret and mhpmcounters. The
first one requires Smcntrpmf while the other one requires Sscofpmf
to be enabled.

The cycle/instret are still computed using host ticks when icount
is not enabled. Otherwise, they are computed using raw icount which
is more accurate in icount mode.

Reviewed-by: Daniel Henrique Barboza 
Signed-off-by: Atish Patra 
---
  target/riscv/cpu.h| 11 +
  target/riscv/cpu_bits.h   |  5 ++
  target/riscv/cpu_helper.c | 17 ++-
  target/riscv/csr.c| 96 ++-
  target/riscv/pmu.c| 64 ++
  target/riscv/pmu.h|  2 +
  6 files changed, 171 insertions(+), 24 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 174e8ba8e847..9e21d7f7d635 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -157,6 +157,15 @@ typedef struct PMUCTRState {
  target_ulong irq_overflow_left;
  } PMUCTRState;
  
+typedef struct PMUFixedCtrState {

+/* Track cycle and icount for each privilege mode */
+uint64_t counter[4];
+uint64_t counter_prev[4];
+/* Track cycle and icount for each privilege mode when V = 1*/
+uint64_t counter_virt[2];
+uint64_t counter_virt_prev[2];
+} PMUFixedCtrState;
+
  struct CPUArchState {
  target_ulong gpr[32];
  target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
@@ -353,6 +362,8 @@ struct CPUArchState {
  /* PMU event selector configured values for RV32 */
  target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
  
+PMUFixedCtrState pmu_fixed_ctrs[2];

+
  target_ulong sscratch;
  target_ulong mscratch;
  
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h

index e866c60a400c..5fe349e313dc 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -920,6 +920,11 @@ typedef enum RISCVException {
  #define MHPMEVENT_BIT_VUINHBIT_ULL(58)
  #define MHPMEVENTH_BIT_VUINH   BIT(26)
  
+#define MHPMEVENT_FILTER_MASK  (MHPMEVENT_BIT_MINH  | \

+MHPMEVENT_BIT_SINH  | \
+MHPMEVENT_BIT_UINH  | \
+MHPMEVENT_BIT_VSINH | \
+MHPMEVENT_BIT_VUINH)
  #define MHPMEVENT_SSCOF_MASK   _ULL(0x)
  #define MHPMEVENT_IDX_MASK 0xF
  #define MHPMEVENT_SSCOF_RESVD  16
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index d462d95ee165..33965d843d46 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -718,8 +718,21 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong 
newpriv)
  {
  g_assert(newpriv <= PRV_M && newpriv != PRV_RESERVED);
  
-if (icount_enabled() && newpriv != env->priv) {

-riscv_itrigger_update_priv(env);
+/*
+ * Invoke cycle/instret update between priv mode changes or
+ * VS->HS mode transition is SPV bit must be set
+ * HS->VS mode transition where virt_enabled must be set
+ * In both cases, priv will S mode only.
+ */
+if (newpriv != env->priv ||
+   (env->priv == PRV_S && newpriv == PRV_S &&
+(env->virt_enabled || get_field(env->hstatus, HSTATUS_SPV {
+if (icount_enabled()) {
+riscv_itrigger_update_priv(env);
+riscv_pmu_icount_update_priv(env, newpriv);
+} else {
+riscv_pmu_cycle_update_priv(env, newpriv);
+}
  }
  /* tlb_flush is unnecessary as mode is contained in mmu_idx */
  env->priv = newpriv;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index ff9bac537593..482e212c5f74 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -788,32 +788,16 @@ static RISCVException write_vcsr(CPURISCVState *env, int 
csrno,
  return RISCV_EXCP_NONE;
  }
  
+#if defined(CONFIG_USER_ONLY)

  /* User Timers and Counters */
  static target_ulong get_ticks(bool shift)
  {
-int64_t val;
-target_ulong result;
-
-#if !defined(CONFIG_USER_ONLY)
-if (icount_enabled()) {
-val = icount_get();
-} else {
-val = cpu_get_host_ticks();
-}
-#else
-val = cpu_get_host_ticks();
-#endif
-
-if (shift) {
-result = val >> 32;
-} else {
-result = val;
-}
+int64_t val = cpu_get_host_ticks();
+target_ulong result = shift ? val >> 32 : val;
  
  return result;

  }
  
-#if defined(CONFIG_USER_ONLY)

  static RISCVException read_time(CPURISCVState *env, int csrno,
  target_ulong *val)
  {
@@ -952,6 +936,71 @@ static RISCVException write_mhpmeventh(CPURISCVState *env, 
int csrno,
  return RISCV_EXCP_NONE;
  }
  
+static 

[PATCH] target/riscv: Enable xtheadsync under user mode

2024-02-03 Thread LIU Zhiwei
According to xtheadsync[1][2] documentation, it can be used in user mode and
the behavior is same with other priviledges.

[1]:https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadsync/sync.adoc
[2]:https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadsync/sync_i.adoc

Signed-off-by: LIU Zhiwei 
---
 target/riscv/insn_trans/trans_xthead.c.inc | 10 --
 1 file changed, 10 deletions(-)

diff --git a/target/riscv/insn_trans/trans_xthead.c.inc 
b/target/riscv/insn_trans/trans_xthead.c.inc
index dbb6411239..22488412d4 100644
--- a/target/riscv/insn_trans/trans_xthead.c.inc
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -992,7 +992,6 @@ static bool trans_th_sfence_vmas(DisasContext *ctx, 
arg_th_sfence_vmas *a)
 #endif
 }
 
-#ifndef CONFIG_USER_ONLY
 static void gen_th_sync_local(DisasContext *ctx)
 {
 /*
@@ -1003,14 +1002,12 @@ static void gen_th_sync_local(DisasContext *ctx)
 tcg_gen_exit_tb(NULL, 0);
 ctx->base.is_jmp = DISAS_NORETURN;
 }
-#endif
 
 static bool trans_th_sync(DisasContext *ctx, arg_th_sync *a)
 {
 (void) a;
 REQUIRE_XTHEADSYNC(ctx);
 
-#ifndef CONFIG_USER_ONLY
 REQUIRE_PRIV_MSU(ctx);
 
 /*
@@ -1019,9 +1016,6 @@ static bool trans_th_sync(DisasContext *ctx, arg_th_sync 
*a)
 gen_th_sync_local(ctx);
 
 return true;
-#else
-return false;
-#endif
 }
 
 static bool trans_th_sync_i(DisasContext *ctx, arg_th_sync_i *a)
@@ -1029,7 +1023,6 @@ static bool trans_th_sync_i(DisasContext *ctx, 
arg_th_sync_i *a)
 (void) a;
 REQUIRE_XTHEADSYNC(ctx);
 
-#ifndef CONFIG_USER_ONLY
 REQUIRE_PRIV_MSU(ctx);
 
 /*
@@ -1038,9 +1031,6 @@ static bool trans_th_sync_i(DisasContext *ctx, 
arg_th_sync_i *a)
 gen_th_sync_local(ctx);
 
 return true;
-#else
-return false;
-#endif
 }
 
 static bool trans_th_sync_is(DisasContext *ctx, arg_th_sync_is *a)
-- 
2.25.1




Re: [PATCH 2/2] target/riscv: Support xtheadmaee for thead-c906

2024-02-03 Thread LIU Zhiwei



On 2024/1/30 19:43, Christoph Müllner wrote:

On Tue, Jan 30, 2024 at 12:12 PM LIU Zhiwei
 wrote:

thead-c906 uses some flags in pte [60-63] bits. It has history reasons that
SVPBMT didn't exist when thead-c906 came to world.

We named this feature as xtheadmaee. this feature is controlled by an custom
CSR named mxstatus, whose maee field encodes whether enable the pte [60-63] 
bits.

The sections "5.2.2.1 Page table structure" and "15.1.7.1 M-mode extension
status register (MXSTATUS)" in document[1] give the detailed information
about its design.

I would prefer if we would not define an extension like XTheadMaee
without a specification.
The linked document defines the bit MAEE in a custom CSR, but the
scope of XTheadMaee
is not clearly defined (the term XTheadMaee is not even part of the PDF).

We have all the XThead* extensions well described here:
   https://github.com/T-head-Semi/thead-extension-spec/tree/master
And it would not be much effort to add XTheadMaee there as well.


Done.  Thanks for the comment. The XTheadMaee specification is here:

https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadmaee.adoc

Thanks,
Zhiwei



For those who don't know the context of this patch, here is the c906
boot regression report from Björn:
   https://lists.gnu.org/archive/html/qemu-devel/2024-01/msg04766.html

BR
Christoph

Christoph


[1]:https://occ-intl-prod.oss-ap-southeast-1.aliyuncs.com/resource//1699265191641/XuanTie-Openc906-UserManual.pdf
Signed-off-by: LIU Zhiwei 
---
  target/riscv/cpu.c |  6 
  target/riscv/cpu.h |  9 ++
  target/riscv/cpu_bits.h|  6 
  target/riscv/cpu_cfg.h |  4 ++-
  target/riscv/cpu_helper.c  | 25 ---
  target/riscv/meson.build   |  1 +
  target/riscv/tcg/tcg-cpu.c |  9 ++
  target/riscv/xthead_csr.c  | 63 ++
  8 files changed, 105 insertions(+), 18 deletions(-)
  create mode 100644 target/riscv/xthead_csr.c

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 2dcbc9ff32..bfdbb0539a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -171,6 +171,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
  ISA_EXT_DATA_ENTRY(xtheadmemidx, PRIV_VERSION_1_11_0, ext_xtheadmemidx),
  ISA_EXT_DATA_ENTRY(xtheadmempair, PRIV_VERSION_1_11_0, ext_xtheadmempair),
  ISA_EXT_DATA_ENTRY(xtheadsync, PRIV_VERSION_1_11_0, ext_xtheadsync),
+ISA_EXT_DATA_ENTRY(xtheadmaee, PRIV_VERSION_1_11_0, ext_xtheadmaee),
  ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, 
ext_XVentanaCondOps),

  DEFINE_PROP_END_OF_LIST(),
@@ -506,6 +507,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)

  cpu->cfg.mvendorid = THEAD_VENDOR_ID;
  #ifndef CONFIG_USER_ONLY
+cpu->cfg.ext_xtheadmaee = true;
  set_satp_mode_max_supported(cpu, VM_1_10_SV39);
  #endif

@@ -949,6 +951,9 @@ static void riscv_cpu_reset_hold(Object *obj)
  }

  pmp_unlock_entries(env);
+if (riscv_cpu_cfg(env)->ext_xtheadmaee) {
+env->th_mxstatus |= TH_MXSTATUS_MAEE;
+}
  #endif
  env->xl = riscv_cpu_mxl(env);
  riscv_cpu_update_mask(env);
@@ -1439,6 +1444,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
  MULTI_EXT_CFG_BOOL("xtheadmemidx", ext_xtheadmemidx, false),
  MULTI_EXT_CFG_BOOL("xtheadmempair", ext_xtheadmempair, false),
  MULTI_EXT_CFG_BOOL("xtheadsync", ext_xtheadsync, false),
+MULTI_EXT_CFG_BOOL("xtheadmaee", ext_xtheadmaee, false),
  MULTI_EXT_CFG_BOOL("xventanacondops", ext_XVentanaCondOps, false),

  DEFINE_PROP_END_OF_LIST(),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5f3955c38d..1bacf40355 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -412,6 +412,14 @@ struct CPUArchState {
  target_ulong cur_pmmask;
  target_ulong cur_pmbase;

+union {
+/* Custom CSR for Xuantie CPU */
+struct {
+#ifndef CONFIG_USER_ONLY
+target_ulong th_mxstatus;
+#endif
+};
+};
  /* Fields from here on are preserved across CPU reset. */
  QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
  QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
@@ -799,6 +807,7 @@ void riscv_add_satp_mode_properties(Object *obj);
  bool riscv_cpu_accelerator_compatible(RISCVCPU *cpu);

  /* CSR function table */
+extern riscv_csr_operations th_csr_ops[CSR_TABLE_SIZE];
  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];

  extern const bool valid_vm_1_10_32[], valid_vm_1_10_64[];
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index e116f6c252..67ebb1cefe 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -897,4 +897,10 @@ typedef enum RISCVException {
  /* JVT CSR bits */
  #define JVT_MODE   0x3F
  #define JVT_BASE   (~0x3F)
+
+/* Xuantie custom CSRs */
+#define CSR_TH_MXSTA

[PATCH v2 1/2] target/riscv: Register vendors CSR

2024-02-03 Thread LIU Zhiwei
riscv specification allows custom CSRs in decode area. So we should
register all vendor CSRs in cpu realize stage.

Signed-off-by: LIU Zhiwei 
---
1) Use int index to quiet the  Werror for "i < 0".
---
 target/riscv/cpu.c |  3 +++
 target/riscv/tcg/tcg-cpu.c | 18 ++
 target/riscv/tcg/tcg-cpu.h |  1 +
 3 files changed, 22 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 8cbfc7e781..2dcbc9ff32 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1113,6 +1113,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if (tcg_enabled()) {
+riscv_tcg_cpu_register_vendor_csr(cpu);
+}
 riscv_cpu_register_gdb_regs_for_features(cs);
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 994ca1cdf9..559bf373f3 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -871,6 +871,24 @@ static void riscv_cpu_validate_profiles(RISCVCPU *cpu)
 }
 }
 
+void riscv_tcg_cpu_register_vendor_csr(RISCVCPU *cpu)
+{
+static const struct {
+bool (*guard_func)(const RISCVCPUConfig *);
+riscv_csr_operations *csr_ops;
+} vendors[] = {
+};
+for (int i = 0; i < ARRAY_SIZE(vendors); ++i) {
+if (!vendors[i].guard_func(>cfg)) {
+continue;
+}
+for (size_t j = 0; j < CSR_TABLE_SIZE &&
+   vendors[i].csr_ops[j].name; j++) {
+csr_ops[j] = vendors[i].csr_ops[j];
+}
+}
+}
+
 void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
 {
 CPURISCVState *env = >env;
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
index f7b32417f8..3daaebf4fb 100644
--- a/target/riscv/tcg/tcg-cpu.h
+++ b/target/riscv/tcg/tcg-cpu.h
@@ -25,5 +25,6 @@
 void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
 void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
 bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
+void riscv_tcg_cpu_register_vendor_csr(RISCVCPU *cpu);
 
 #endif
-- 
2.25.1




[PATCH v2 2/2] target/riscv: Support xtheadmaee for thead-c906

2024-02-03 Thread LIU Zhiwei
This patch set fix the regression on kernel pointed by Björn Töpel in
https://www.mail-archive.com/qemu-devel@nongnu.org/msg1018232.html.

thead-c906 uses some flags in pte [60-63] bits. It has history reasons that
SVPBMT didn't exist when thead-c906 came to wotrld. We named this feature as
xtheadmaee[1]. this feature is controlled by an custom CSR named mxstatus,
whose maee field encodes whether enable the pte [60-63] bits.

[1]:https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadmaee.adoc

Signed-off-by: LIU Zhiwei 
---
v1->v2:
1) Remove mxstatus user mode access
2) Add reference documentation to the commit log
---
 target/riscv/cpu.c |  6 
 target/riscv/cpu.h |  9 ++
 target/riscv/cpu_bits.h|  6 
 target/riscv/cpu_cfg.h |  4 ++-
 target/riscv/cpu_helper.c  | 25 ---
 target/riscv/meson.build   |  1 +
 target/riscv/tcg/tcg-cpu.c |  7 +++-
 target/riscv/xthead_csr.c  | 65 ++
 8 files changed, 110 insertions(+), 13 deletions(-)
 create mode 100644 target/riscv/xthead_csr.c

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 2dcbc9ff32..bfdbb0539a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -171,6 +171,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(xtheadmemidx, PRIV_VERSION_1_11_0, ext_xtheadmemidx),
 ISA_EXT_DATA_ENTRY(xtheadmempair, PRIV_VERSION_1_11_0, ext_xtheadmempair),
 ISA_EXT_DATA_ENTRY(xtheadsync, PRIV_VERSION_1_11_0, ext_xtheadsync),
+ISA_EXT_DATA_ENTRY(xtheadmaee, PRIV_VERSION_1_11_0, ext_xtheadmaee),
 ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, 
ext_XVentanaCondOps),
 
 DEFINE_PROP_END_OF_LIST(),
@@ -506,6 +507,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
 
 cpu->cfg.mvendorid = THEAD_VENDOR_ID;
 #ifndef CONFIG_USER_ONLY
+cpu->cfg.ext_xtheadmaee = true;
 set_satp_mode_max_supported(cpu, VM_1_10_SV39);
 #endif
 
@@ -949,6 +951,9 @@ static void riscv_cpu_reset_hold(Object *obj)
 }
 
 pmp_unlock_entries(env);
+if (riscv_cpu_cfg(env)->ext_xtheadmaee) {
+env->th_mxstatus |= TH_MXSTATUS_MAEE;
+}
 #endif
 env->xl = riscv_cpu_mxl(env);
 riscv_cpu_update_mask(env);
@@ -1439,6 +1444,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
 MULTI_EXT_CFG_BOOL("xtheadmemidx", ext_xtheadmemidx, false),
 MULTI_EXT_CFG_BOOL("xtheadmempair", ext_xtheadmempair, false),
 MULTI_EXT_CFG_BOOL("xtheadsync", ext_xtheadsync, false),
+MULTI_EXT_CFG_BOOL("xtheadmaee", ext_xtheadmaee, false),
 MULTI_EXT_CFG_BOOL("xventanacondops", ext_XVentanaCondOps, false),
 
 DEFINE_PROP_END_OF_LIST(),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5f3955c38d..1bacf40355 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -412,6 +412,14 @@ struct CPUArchState {
 target_ulong cur_pmmask;
 target_ulong cur_pmbase;
 
+union {
+/* Custom CSR for Xuantie CPU */
+struct {
+#ifndef CONFIG_USER_ONLY
+target_ulong th_mxstatus;
+#endif
+};
+};
 /* Fields from here on are preserved across CPU reset. */
 QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
 QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
@@ -799,6 +807,7 @@ void riscv_add_satp_mode_properties(Object *obj);
 bool riscv_cpu_accelerator_compatible(RISCVCPU *cpu);
 
 /* CSR function table */
+extern riscv_csr_operations th_csr_ops[CSR_TABLE_SIZE];
 extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
 
 extern const bool valid_vm_1_10_32[], valid_vm_1_10_64[];
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index e116f6c252..67ebb1cefe 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -897,4 +897,10 @@ typedef enum RISCVException {
 /* JVT CSR bits */
 #define JVT_MODE   0x3F
 #define JVT_BASE   (~0x3F)
+
+/* Xuantie custom CSRs */
+#define CSR_TH_MXSTATUS 0x7c0
+
+#define TH_MXSTATUS_MAEE_SHIFT  21
+#define TH_MXSTATUS_MAEE(0x1 << TH_MXSTATUS_MAEE_SHIFT)
 #endif
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 780ae6ef17..3735c69fd6 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -136,6 +136,7 @@ struct RISCVCPUConfig {
 bool ext_xtheadmemidx;
 bool ext_xtheadmempair;
 bool ext_xtheadsync;
+bool ext_xtheadmaee;
 bool ext_XVentanaCondOps;
 
 uint32_t pmu_mask;
@@ -176,7 +177,8 @@ static inline bool has_xthead_p(const RISCVCPUConfig *cfg)
cfg->ext_xtheadcondmov ||
cfg->ext_xtheadfmemidx || cfg->ext_xtheadfmv ||
cfg->ext_xtheadmac || cfg->ext_xtheadmemidx ||
-   cfg->ext_xtheadmempair || cfg->ext_xtheadsync;
+   cfg->ext_xtheadmempair || cfg->ext_xtheadsync ||
+   cfg->ext_xtheadmaee;
 }
 
 #define M

[PATCH v2 0/2] target/riscv: Support mxstatus CSR for thead-c906

2024-02-03 Thread LIU Zhiwei
This patch set fix the regression on kernel pointed by Björn Töpel in
https://www.mail-archive.com/qemu-devel@nongnu.org/msg1018232.html.

We first add a framework for vendor CSRs in patch 1. After that we add
one thead-c906 CSR mxstatus, which is used for mmu extension xtheadmaee.

thead-c906 uses some flags in pte [60-63] bits. It has history reasons that
SVPBMT didn't exist when thead-c906 came to wotrld. We named this feature as
xtheadmaee[1]. this feature is controlled by an custom CSR named mxstatus,
whose maee field encodes whether enable the pte [60-63] bits.

[1]:https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadmaee.adoc

LIU Zhiwei (2):
  target/riscv: Register vendors CSR
  target/riscv: Support xtheadmaee for thead-c906

 target/riscv/cpu.c |  9 ++
 target/riscv/cpu.h |  9 ++
 target/riscv/cpu_bits.h|  6 
 target/riscv/cpu_cfg.h |  4 ++-
 target/riscv/cpu_helper.c  | 25 ---
 target/riscv/meson.build   |  1 +
 target/riscv/tcg/tcg-cpu.c | 25 ++-
 target/riscv/tcg/tcg-cpu.h |  1 +
 target/riscv/xthead_csr.c  | 65 ++
 9 files changed, 132 insertions(+), 13 deletions(-)
 create mode 100644 target/riscv/xthead_csr.c

-- 
2.25.1




Re: [PATCH 2/2] target/riscv: Support xtheadmaee for thead-c906

2024-01-30 Thread LIU Zhiwei



On 2024/1/31 13:07, Richard Henderson wrote:

On 1/30/24 21:11, LIU Zhiwei wrote:

+riscv_csr_operations th_csr_ops[CSR_TABLE_SIZE] = {
+#if !defined(CONFIG_USER_ONLY)
+    [CSR_TH_MXSTATUS] = { "th_mxstatus", th_maee_check, 
read_th_mxstatus,

+ write_th_mxstatus},
+#endif /* !CONFIG_USER_ONLY */
+};


This is clearly the wrong data structure for a single entry in the array.


This array should have the same size with csr_ops so that we can 
override custom CSR behavior directly. Besides, It will have other 
entries in the near future.


I see that I missed surround the th_maee_check, read_th_mxstatus, 
write_mxstatus with !CONFIG_USER_ONLY.  But I don't understand why it is 
wrong for a single entry in the array, at least the compiler think it 
has no error.


Thanks,
Zhiwei




r~





Re: [PATCH 1/2] target/riscv: Register vendors CSR

2024-01-30 Thread LIU Zhiwei



On 2024/1/31 13:06, Richard Henderson wrote:

On 1/30/24 21:11, LIU Zhiwei wrote:

+/* This stub just works for making vendors array not empty */
+riscv_csr_operations stub_csr_ops[CSR_TABLE_SIZE];
+static inline bool never_p(const RISCVCPUConfig *cfg)
+{
+    return false;
+}
+
+void riscv_tcg_cpu_register_vendor_csr(RISCVCPU *cpu)
+{
+    static const struct {
+    bool (*guard_func)(const RISCVCPUConfig *);
+    riscv_csr_operations *csr_ops;
+    } vendors[] = {
+    { never_p, stub_csr_ops },
+    };
+    for (size_t i = 0; i < ARRAY_SIZE(vendors); ++i) {


Presumably you did this to avoid a Werror for "i < 0", since i is 
unsigned.

Yes. That's the gcc complains.


It would be better to either use "int i"

OK

, or

  for (size_t i = 0, n = ARRAY_SIZE(vendors); i < n; ++i)

either of which will not Werror.

This works.  I don't know why it works, because n is 0 and never changes.


Especially considering the size of stub_csr_ops.


Do you mean we should remove the stub_csr_ops? I don't know how to 
relate your two solving ways to stub_csr_ops.


Thanks,
Zhiwei



r~





[PATCH 2/2] target/riscv: Support xtheadmaee for thead-c906

2024-01-30 Thread LIU Zhiwei
thead-c906 uses some flags in pte [60-63] bits. It has history reasons that
SVPBMT didn't exist when thead-c906 came to world.

We named this feature as xtheadmaee. this feature is controlled by an custom
CSR named mxstatus, whose maee field encodes whether enable the pte [60-63] 
bits.

The sections "5.2.2.1 Page table structure" and "15.1.7.1 M-mode extension
status register (MXSTATUS)" in document[1] give the detailed information
about its design.

[1]:https://occ-intl-prod.oss-ap-southeast-1.aliyuncs.com/resource//1699265191641/XuanTie-Openc906-UserManual.pdf
Signed-off-by: LIU Zhiwei 
---
 target/riscv/cpu.c |  6 
 target/riscv/cpu.h |  9 ++
 target/riscv/cpu_bits.h|  6 
 target/riscv/cpu_cfg.h |  4 ++-
 target/riscv/cpu_helper.c  | 25 ---
 target/riscv/meson.build   |  1 +
 target/riscv/tcg/tcg-cpu.c |  9 ++
 target/riscv/xthead_csr.c  | 63 ++
 8 files changed, 105 insertions(+), 18 deletions(-)
 create mode 100644 target/riscv/xthead_csr.c

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 2dcbc9ff32..bfdbb0539a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -171,6 +171,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(xtheadmemidx, PRIV_VERSION_1_11_0, ext_xtheadmemidx),
 ISA_EXT_DATA_ENTRY(xtheadmempair, PRIV_VERSION_1_11_0, ext_xtheadmempair),
 ISA_EXT_DATA_ENTRY(xtheadsync, PRIV_VERSION_1_11_0, ext_xtheadsync),
+ISA_EXT_DATA_ENTRY(xtheadmaee, PRIV_VERSION_1_11_0, ext_xtheadmaee),
 ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, 
ext_XVentanaCondOps),
 
 DEFINE_PROP_END_OF_LIST(),
@@ -506,6 +507,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
 
 cpu->cfg.mvendorid = THEAD_VENDOR_ID;
 #ifndef CONFIG_USER_ONLY
+cpu->cfg.ext_xtheadmaee = true;
 set_satp_mode_max_supported(cpu, VM_1_10_SV39);
 #endif
 
@@ -949,6 +951,9 @@ static void riscv_cpu_reset_hold(Object *obj)
 }
 
 pmp_unlock_entries(env);
+if (riscv_cpu_cfg(env)->ext_xtheadmaee) {
+env->th_mxstatus |= TH_MXSTATUS_MAEE;
+}
 #endif
 env->xl = riscv_cpu_mxl(env);
 riscv_cpu_update_mask(env);
@@ -1439,6 +1444,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
 MULTI_EXT_CFG_BOOL("xtheadmemidx", ext_xtheadmemidx, false),
 MULTI_EXT_CFG_BOOL("xtheadmempair", ext_xtheadmempair, false),
 MULTI_EXT_CFG_BOOL("xtheadsync", ext_xtheadsync, false),
+MULTI_EXT_CFG_BOOL("xtheadmaee", ext_xtheadmaee, false),
 MULTI_EXT_CFG_BOOL("xventanacondops", ext_XVentanaCondOps, false),
 
 DEFINE_PROP_END_OF_LIST(),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5f3955c38d..1bacf40355 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -412,6 +412,14 @@ struct CPUArchState {
 target_ulong cur_pmmask;
 target_ulong cur_pmbase;
 
+union {
+/* Custom CSR for Xuantie CPU */
+struct {
+#ifndef CONFIG_USER_ONLY
+target_ulong th_mxstatus;
+#endif
+};
+};
 /* Fields from here on are preserved across CPU reset. */
 QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
 QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
@@ -799,6 +807,7 @@ void riscv_add_satp_mode_properties(Object *obj);
 bool riscv_cpu_accelerator_compatible(RISCVCPU *cpu);
 
 /* CSR function table */
+extern riscv_csr_operations th_csr_ops[CSR_TABLE_SIZE];
 extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
 
 extern const bool valid_vm_1_10_32[], valid_vm_1_10_64[];
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index e116f6c252..67ebb1cefe 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -897,4 +897,10 @@ typedef enum RISCVException {
 /* JVT CSR bits */
 #define JVT_MODE   0x3F
 #define JVT_BASE   (~0x3F)
+
+/* Xuantie custom CSRs */
+#define CSR_TH_MXSTATUS 0x7c0
+
+#define TH_MXSTATUS_MAEE_SHIFT  21
+#define TH_MXSTATUS_MAEE(0x1 << TH_MXSTATUS_MAEE_SHIFT)
 #endif
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 780ae6ef17..3735c69fd6 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -136,6 +136,7 @@ struct RISCVCPUConfig {
 bool ext_xtheadmemidx;
 bool ext_xtheadmempair;
 bool ext_xtheadsync;
+bool ext_xtheadmaee;
 bool ext_XVentanaCondOps;
 
 uint32_t pmu_mask;
@@ -176,7 +177,8 @@ static inline bool has_xthead_p(const RISCVCPUConfig *cfg)
cfg->ext_xtheadcondmov ||
cfg->ext_xtheadfmemidx || cfg->ext_xtheadfmv ||
cfg->ext_xtheadmac || cfg->ext_xtheadmemidx ||
-   cfg->ext_xtheadmempair || cfg->ext_xtheadsync;
+   cfg->ext_xtheadmempair || cfg->ext_xtheadsync ||
+   cfg->ext_xtheadmaee;
 }
 
 #define MATERIALISE_EXT_PREDICATE(ext) \

[PATCH 1/2] target/riscv: Register vendors CSR

2024-01-30 Thread LIU Zhiwei
riscv specification allows custom CSRs in decode area. So we should
register all vendor CSRs in cpu realize stage.

Signed-off-by: LIU Zhiwei 
---
 target/riscv/cpu.c |  3 +++
 target/riscv/tcg/tcg-cpu.c | 26 ++
 target/riscv/tcg/tcg-cpu.h |  1 +
 3 files changed, 30 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 8cbfc7e781..2dcbc9ff32 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1113,6 +1113,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if (tcg_enabled()) {
+riscv_tcg_cpu_register_vendor_csr(cpu);
+}
 riscv_cpu_register_gdb_regs_for_features(cs);
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 994ca1cdf9..408b2ebffa 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -871,6 +871,32 @@ static void riscv_cpu_validate_profiles(RISCVCPU *cpu)
 }
 }
 
+/* This stub just works for making vendors array not empty */
+riscv_csr_operations stub_csr_ops[CSR_TABLE_SIZE];
+static inline bool never_p(const RISCVCPUConfig *cfg)
+{
+return false;
+}
+
+void riscv_tcg_cpu_register_vendor_csr(RISCVCPU *cpu)
+{
+static const struct {
+bool (*guard_func)(const RISCVCPUConfig *);
+riscv_csr_operations *csr_ops;
+} vendors[] = {
+{ never_p, stub_csr_ops },
+};
+for (size_t i = 0; i < ARRAY_SIZE(vendors); ++i) {
+if (!vendors[i].guard_func(>cfg)) {
+continue;
+}
+for (size_t j = 0; j < CSR_TABLE_SIZE &&
+   vendors[i].csr_ops[j].name; j++) {
+csr_ops[j] = vendors[i].csr_ops[j];
+}
+}
+}
+
 void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
 {
 CPURISCVState *env = >env;
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
index f7b32417f8..3daaebf4fb 100644
--- a/target/riscv/tcg/tcg-cpu.h
+++ b/target/riscv/tcg/tcg-cpu.h
@@ -25,5 +25,6 @@
 void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
 void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
 bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
+void riscv_tcg_cpu_register_vendor_csr(RISCVCPU *cpu);
 
 #endif
-- 
2.25.1




[PATCH 0/2] target/riscv: Support mxstatus CSR for thead-c906

2024-01-30 Thread LIU Zhiwei
We first add a framework for vendor CSRs in patch 1. After that we add
one thead-c906 CSR mxstatus, which is used for mmu extension xtheadmaee.

This patch set fix the regression on kernel pointed by Björn Töpel in
https://www.mail-archive.com/qemu-devel@nongnu.org/msg1018232.html.

LIU Zhiwei (2):
  target/riscv: Register vendors CSR
  target/riscv: Support xtheadmaee for thead-c906

 target/riscv/cpu.c |  9 ++
 target/riscv/cpu.h |  9 ++
 target/riscv/cpu_bits.h|  6 
 target/riscv/cpu_cfg.h |  4 ++-
 target/riscv/cpu_helper.c  | 25 ---
 target/riscv/meson.build   |  1 +
 target/riscv/tcg/tcg-cpu.c | 25 ++-
 target/riscv/tcg/tcg-cpu.h |  1 +
 target/riscv/xthead_csr.c  | 63 ++
 9 files changed, 130 insertions(+), 13 deletions(-)
 create mode 100644 target/riscv/xthead_csr.c

-- 
2.25.1




[PATCH] target/riscv: FCSR doesn't contain vxrm and vxsat

2024-01-30 Thread LIU Zhiwei
vxrm and vxsat have been moved into a special register vcsr since
RVV v1.0. So remove them from FCSR for vector 1.0.

Signed-off-by: LIU Zhiwei 
---
 target/riscv/cpu_bits.h | 8 
 1 file changed, 8 deletions(-)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index ebd7917d49..e116f6c252 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -32,14 +32,6 @@
 #define FSR_NXA (FPEXC_NX << FSR_AEXC_SHIFT)
 #define FSR_AEXC(FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
 
-/* Vector Fixed-Point round model */
-#define FSR_VXRM_SHIFT  9
-#define FSR_VXRM(0x3 << FSR_VXRM_SHIFT)
-
-/* Vector Fixed-Point saturation flag */
-#define FSR_VXSAT_SHIFT 8
-#define FSR_VXSAT   (0x1 << FSR_VXSAT_SHIFT)
-
 /* Control and Status Registers */
 
 /* User Trap Setup */
-- 
2.25.1




[PATCH] target/riscv: Use RISCVException as return type for all csr ops

2024-01-30 Thread LIU Zhiwei
The real return value type has been converted to RISCVException,
but some function declarations still not. This patch makes all
csr operation declarations use RISCVExcetion.

Signed-off-by: LIU Zhiwei 
---
 target/riscv/csr.c | 117 -
 1 file changed, 74 insertions(+), 43 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 674ea075a4..ac9a856cc5 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -242,7 +242,7 @@ static RISCVException any32(CPURISCVState *env, int csrno)
 
 }
 
-static int aia_any(CPURISCVState *env, int csrno)
+static RISCVException aia_any(CPURISCVState *env, int csrno)
 {
 if (!riscv_cpu_cfg(env)->ext_smaia) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -251,7 +251,7 @@ static int aia_any(CPURISCVState *env, int csrno)
 return any(env, csrno);
 }
 
-static int aia_any32(CPURISCVState *env, int csrno)
+static RISCVException aia_any32(CPURISCVState *env, int csrno)
 {
 if (!riscv_cpu_cfg(env)->ext_smaia) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -269,7 +269,7 @@ static RISCVException smode(CPURISCVState *env, int csrno)
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
-static int smode32(CPURISCVState *env, int csrno)
+static RISCVException smode32(CPURISCVState *env, int csrno)
 {
 if (riscv_cpu_mxl(env) != MXL_RV32) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -278,7 +278,7 @@ static int smode32(CPURISCVState *env, int csrno)
 return smode(env, csrno);
 }
 
-static int aia_smode(CPURISCVState *env, int csrno)
+static RISCVException aia_smode(CPURISCVState *env, int csrno)
 {
 if (!riscv_cpu_cfg(env)->ext_ssaia) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -287,7 +287,7 @@ static int aia_smode(CPURISCVState *env, int csrno)
 return smode(env, csrno);
 }
 
-static int aia_smode32(CPURISCVState *env, int csrno)
+static RISCVException aia_smode32(CPURISCVState *env, int csrno)
 {
 if (!riscv_cpu_cfg(env)->ext_ssaia) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -496,7 +496,7 @@ static RISCVException pointer_masking(CPURISCVState *env, 
int csrno)
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
-static int aia_hmode(CPURISCVState *env, int csrno)
+static RISCVException aia_hmode(CPURISCVState *env, int csrno)
 {
 if (!riscv_cpu_cfg(env)->ext_ssaia) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -505,7 +505,7 @@ static int aia_hmode(CPURISCVState *env, int csrno)
  return hmode(env, csrno);
 }
 
-static int aia_hmode32(CPURISCVState *env, int csrno)
+static RISCVException aia_hmode32(CPURISCVState *env, int csrno)
 {
 if (!riscv_cpu_cfg(env)->ext_ssaia) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -681,7 +681,8 @@ static RISCVException read_vl(CPURISCVState *env, int csrno,
 return RISCV_EXCP_NONE;
 }
 
-static int read_vlenb(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_vlenb(CPURISCVState *env, int csrno,
+ target_ulong *val)
 {
 *val = riscv_cpu_cfg(env)->vlen >> 3;
 return RISCV_EXCP_NONE;
@@ -742,13 +743,15 @@ static RISCVException write_vstart(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 
-static int read_vcsr(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_vcsr(CPURISCVState *env, int csrno,
+target_ulong *val)
 {
 *val = (env->vxrm << VCSR_VXRM_SHIFT) | (env->vxsat << VCSR_VXSAT_SHIFT);
 return RISCV_EXCP_NONE;
 }
 
-static int write_vcsr(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_vcsr(CPURISCVState *env, int csrno,
+ target_ulong val)
 {
 #if !defined(CONFIG_USER_ONLY)
 env->mstatus |= MSTATUS_VS;
@@ -798,13 +801,15 @@ static RISCVException read_timeh(CPURISCVState *env, int 
csrno,
 return RISCV_EXCP_NONE;
 }
 
-static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_hpmcounter(CPURISCVState *env, int csrno,
+  target_ulong *val)
 {
 *val = get_ticks(false);
 return RISCV_EXCP_NONE;
 }
 
-static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_hpmcounterh(CPURISCVState *env, int csrno,
+   target_ulong *val)
 {
 *val = get_ticks(true);
 return RISCV_EXCP_NONE;
@@ -812,7 +817,8 @@ static int read_hpmcounterh(CPURISCVState *env, int csrno, 
target_ulong *val)
 
 #else /* CONFIG_USER_ONLY */
 
-static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mhpmevent(CPURISCVState *env, int csrno,
+ target_ulong *val)
 {
 int evt_index = csrno - CSR_MCOUNTINHIBIT;
 
@@ -821,7 +827,8 @@ static int read_mhpmevent(CPURISCVState *env, int csrno, 
target_ulong *val)
 return RISCV_EXCP_NONE;
 }
 
-static int write_mhpmevent(CPURISCV

Re: qemu riscv, thead c906, Linux boot regression

2024-01-25 Thread LIU Zhiwei



On 2024/1/24 20:49, Björn Töpel wrote:

Hi!

I bumped the RISC-V Linux kernel CI to use qemu 8.2.0, and realized that
thead c906 didn't boot anymore. Bisection points to commit d6a427e2c0b2
("target/riscv/cpu.c: restrict 'marchid' value")

Reverting that commit, or the hack below solves the boot issue:

--8<--
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 8cbfc7e781ad..e18596c8a55a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -505,6 +505,9 @@ static void rv64_thead_c906_cpu_init(Object *obj)
  cpu->cfg.ext_xtheadsync = true;
  
  cpu->cfg.mvendorid = THEAD_VENDOR_ID;

+cpu->cfg.marchid = ((QEMU_VERSION_MAJOR << 16) |
+(QEMU_VERSION_MINOR << 8)  |
+(QEMU_VERSION_MICRO));
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(cpu, VM_1_10_SV39);
  #endif
--8<--

I'm unsure what the correct qemu way of adding a default value is,
or if c906 should have a proper marchid.

Maybe Christoph or Zhiwei can answer?

qemu command-line:
qemu-system-riscv64 -nodefaults -nographic -machine virt,acpi=off \
-cpu thead-c906 ...


Hi  Björn,

I think it is caused by an mmu extension(named XTheadMaee) not 
implemented on QEMU which is conflicts with Svpbmt, which is the reason 
for error-ta in Linux.


I will try to fix this on QEMU and at the same time give a way to 
implement vendor custom CSR(XTheadMaee is controlled by an CSR named 
mexstatus)  on QEMU.


Thanks,
Zhiwei



Thanks,
Björn




[PATCH 1/1] target/riscv: Not allow write mstatus_vs without RVV

2023-12-14 Thread LIU Zhiwei
If CPU does not implement the Vector extension, it usually means
mstatus vs hardwire to zero. So we should not allow write a
non-zero value to this field.

Signed-off-by: LIU Zhiwei 
---
 target/riscv/csr.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index fde7ce1a53..d1de6b2390 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1328,11 +1328,14 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
 mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
 MSTATUS_SPP | MSTATUS_MPRV | MSTATUS_SUM |
 MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
-MSTATUS_TW | MSTATUS_VS;
+MSTATUS_TW;
 
 if (riscv_has_ext(env, RVF)) {
 mask |= MSTATUS_FS;
 }
+if (riscv_has_ext(env, RVV)) {
+mask |= MSTATUS_VS;
+}
 
 if (xl != MXL_RV32 || env->debugger) {
 if (riscv_has_ext(env, RVH)) {
-- 
2.25.1




[PATCH for 8.2] target/riscv: Fix th.dcache.cval1 priviledge check

2023-12-08 Thread LIU Zhiwei
According to the specification, the th.dcache.cvall1 can be executed
under all priviledges.
The specification about xtheadcmo located in,
https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadcmo/dcache_cval1.adoc

Signed-off-by: LIU Zhiwei 
---
 target/riscv/insn_trans/trans_xthead.c.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/insn_trans/trans_xthead.c.inc 
b/target/riscv/insn_trans/trans_xthead.c.inc
index 810d76665a..dbb6411239 100644
--- a/target/riscv/insn_trans/trans_xthead.c.inc
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -296,7 +296,7 @@ NOP_PRIVCHECK(th_dcache_csw, REQUIRE_XTHEADCMO, 
REQUIRE_PRIV_MS)
 NOP_PRIVCHECK(th_dcache_cisw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
 NOP_PRIVCHECK(th_dcache_isw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
 NOP_PRIVCHECK(th_dcache_cpal1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
-NOP_PRIVCHECK(th_dcache_cval1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
+NOP_PRIVCHECK(th_dcache_cval1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
 
 NOP_PRIVCHECK(th_icache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
 NOP_PRIVCHECK(th_icache_ialls, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
-- 
2.17.1




Re: [PATCH 1/2] target/riscv: FIX xATP_MODE validation

2023-12-07 Thread LIU Zhiwei

Hi Irina,

On 2023/12/1 19:53, Irina Ryapolova wrote:

The SATP register is an SXLEN-bit read/write WARL register. It means that CSR 
fields are only defined
for a subset of bit encodings, but allow any value to be written while 
guaranteeing to return a legal
value whenever read (See riscv-privileged-20211203, SATP CSR).

For example on rv64 we are trying to write to SATP CSR val = 0x1000 
(SATP_MODE = 1 - Reserved for standard use)
and after that we are trying to read SATP_CSR. We read from the SATP CSR value 
= 0x1000, which is not a correct
operation (return illegal value).

Signed-off-by: Irina Ryapolova 
---
  target/riscv/csr.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index fde7ce1a53..6f244815b7 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1278,8 +1278,8 @@ static RISCVException read_mstatus(CPURISCVState *env, 
int csrno,
  
  static bool validate_vm(CPURISCVState *env, target_ulong vm)

  {
-return (vm & 0xf) <=
-   satp_mode_max_from_map(riscv_cpu_cfg(env)->satp_mode.map);
+uint64_t mode_supported = riscv_cpu_cfg(env)->satp_mode.supported;


Why not use satp_mode.map? Using satp_mode.supported will violate the 
SATP settings in cpu init.


Zhiwei


+return get_field(mode_supported, (1 << vm));
  }
  
  static target_ulong legalize_mpp(CPURISCVState *env, target_ulong old_mpp,




Re: [PATCH 1/1] accel/tcg: Fix the comment for CPUTLBEntryFull

2023-12-07 Thread LIU Zhiwei



On 2023/11/28 21:04, Mark Cave-Ayland wrote:

On 01/09/2023 07:01, LIU Zhiwei wrote:


When memory region is ram, the lower TARGET_PAGE_BITS is not the
physical section number. Instead, its value is always 0.

Add comment and assert to make it clear.

Signed-off-by: LIU Zhiwei 
---
  accel/tcg/cputlb.c  | 11 +++
  include/exec/cpu-defs.h | 12 ++--
  2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index d68fa6867c..a1ebf75068 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1192,6 +1192,7 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx,
  write_flags = read_flags;
  if (is_ram) {
  iotlb = memory_region_get_ram_addr(section->mr) + xlat;
+    assert(!(iotlb & ~TARGET_PAGE_MASK));
  /*
   * Computing is_clean is expensive; avoid all that unless
   * the page is actually writable.
@@ -1254,10 +1255,12 @@ void tlb_set_page_full(CPUState *cpu, int 
mmu_idx,

    /* refill the tlb */
  /*
- * At this point iotlb contains a physical section number in the 
lower

- * TARGET_PAGE_BITS, and either
- *  + the ram_addr_t of the page base of the target RAM (RAM)
- *  + the offset within section->mr of the page base (I/O, ROMD)
+ * When memory region is ram, iotlb contains a TARGET_PAGE_BITS
+ * aligned ram_addr_t of the page base of the target RAM.
+ * Otherwise, iotlb contains
+ *  - a physical section number in the lower TARGET_PAGE_BITS
+ *  - the offset within section->mr of the page base (I/O, ROMD) 
with the

+ *    TARGET_PAGE_BITS masked off.
   * We subtract addr_page (which is page aligned and thus won't
   * disturb the low bits) to give an offset which can be added 
to the

   * (non-page-aligned) vaddr of the eventual memory access to get
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index fb4c8d480f..350287852e 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -100,12 +100,12 @@
  typedef struct CPUTLBEntryFull {
  /*
   * @xlat_section contains:
- *  - in the lower TARGET_PAGE_BITS, a physical section number
- *  - with the lower TARGET_PAGE_BITS masked off, an offset which
- *    must be added to the virtual address to obtain:
- * + the ram_addr_t of the target RAM (if the physical section
- *   number is PHYS_SECTION_NOTDIRTY or PHYS_SECTION_ROM)
- * + the offset within the target MemoryRegion (otherwise)
+ *  - For ram, an offset which must be added to the virtual address
+ *    to obtain the ram_addr_t of the target RAM
+ *  - For other memory regions,
+ * + in the lower TARGET_PAGE_BITS, the physical section number
+ * + with the TARGET_PAGE_BITS masked off, the offset within
+ *   the target MemoryRegion
   */
  hwaddr xlat_section;


Someone sent me a test case that triggers the assert() introduced by 
this commit dff1ab6 ("accel/tcg: Fix the comment for CPUTLBEntryFull") 
for qemu-system-m68k which is still present in git master. The 
reproducer is easy:


1. Grab the machine ROM file from 
https://www.ilande.co.uk/tmp/qemu/tQuadra800.rom


2. Create an empty declaration ROM greater than 4K:

   dd if=/dev/zero of=/tmp/badrom bs=512 count=12

3. Start QEMU like this:

   qemu-system-m68k -M q800 -bios tQuadra800.rom \
   -device nubus-macfb,romfile=/tmp/badrom

The QEMU process hits the assert() with the following backtrace:

(gdb) bt
#0  0x758a9d3c in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x7585af32 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x75845472 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#3  0x75845395 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4  0x75853e32 in __assert_fail () from 
/lib/x86_64-linux-gnu/libc.so.6
#5  0x55942e0a in tlb_set_page_full (cpu=0x5618d4a0, 
mmu_idx=0, addr=4244631552, full=0x7fffe7d7f7c0) at 
../accel/tcg/cputlb.c:1171
#6  0x559432a0 in tlb_set_page_with_attrs (cpu=0x5618d4a0, 
addr=4244631552, paddr=4244631552, attrs=..., prot=7, mmu_idx=0, 
size=4096) at ../accel/tcg/cputlb.c:1290
#7  0x55943305 in tlb_set_page (cpu=0x5618d4a0, 
addr=4244631552, paddr=4244631552, prot=7, mmu_idx=0, size=4096) at 
../accel/tcg/cputlb.c:1297
#8  0x5588aade in m68k_cpu_tlb_fill (cs=0x5618d4a0, 
address=4244635647, size=1, qemu_access_type=MMU_DATA_LOAD, mmu_idx=0, 
probe=false, retaddr=140734805255937) at ../target/m68k/helper.c:1018
#9  0x55943367 in tlb_fill (cpu=0x5618d4a0, 
addr=4244635647, size=1, access_type=MMU_DATA_LOAD, mmu_idx=0, 
retaddr=140734805255937) at ../accel/tcg/cputlb.c:1315
#10 0x55945d78 in mmu_lookup1 (cpu=0x5618d4a0, 
data=0x7fffe7d7fa00, mmu_idx=0, access_type=MMU_DATA_LOAD, 
ra=140734805255937) at ../accel/tcg/cputlb.c:1713
#11 0x55946081 in mmu_lookup (cp

[PATCH for 8.2] accel/tcg/cputlb: Fix iotlb page alignment check

2023-12-07 Thread LIU Zhiwei
For ram memory region the iotlb(which will be filled into the xlat_section
of CPUTLBEntryFull) is calculated as:

iotlb = memory_region_get_ram_addr(section->mr) + xlat;

1) xlat here is the offset_within_region of a MemoryRegionSection, which maybe
not TARGET_PAGE_BITS aligned.
2) The ram_addr_t returned by memory_region_get_ram_addr is always
HOST PAGE ALIGNED.

So we cann't assert the sum of them is TARGET_PAGE_BITS aligend.
A fail case has been give by the link:
https://lore.kernel.org/all/b68ab7d3-d3d3-9f81-569d-454ae9c11...@linaro.org/T/

Fixes: dff1ab68d8c5 ("accel/tcg: Fix the comment for CPUTLBEntryFull")
Signed-off-by: LIU Zhiwei 
---
 accel/tcg/cputlb.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index db3f93fda9..7a50a21a2e 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1168,7 +1168,6 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx,
 write_flags = read_flags;
 if (is_ram) {
 iotlb = memory_region_get_ram_addr(section->mr) + xlat;
-assert(!(iotlb & ~TARGET_PAGE_MASK));
 /*
  * Computing is_clean is expensive; avoid all that unless
  * the page is actually writable.
@@ -1231,9 +1230,8 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx,
 
 /* refill the tlb */
 /*
- * When memory region is ram, iotlb contains a TARGET_PAGE_BITS
- * aligned ram_addr_t of the page base of the target RAM.
- * Otherwise, iotlb contains
+ * When memory region is ram, iotlb contains ram_addr_t of the page base
+ * of the target RAM. Otherwise, iotlb contains
  *  - a physical section number in the lower TARGET_PAGE_BITS
  *  - the offset within section->mr of the page base (I/O, ROMD) with the
  *TARGET_PAGE_BITS masked off.
-- 
2.17.1




Re: [PATCH 1/1] MAINTAINERS: update mail address for Weiwei Li

2023-10-30 Thread LIU Zhiwei



On 2023/10/30 16:16, Weiwei Li wrote:

My Iscas mail account will be disabled soon, change to my personal
gmail account.

Signed-off-by: Weiwei Li 
---
  MAINTAINERS | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index cd8d6b140f..aa5c5d4bff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -323,7 +323,7 @@ RISC-V TCG CPUs
  M: Palmer Dabbelt 
  M: Alistair Francis 
  M: Bin Meng 
-R: Weiwei Li 
+R: Weiwei Li 
  R: Daniel Henrique Barboza 
  R: Liu Zhiwei 
  L: qemu-ri...@nongnu.org


Reviewed-by: LIU Zhiwei 

Zhiwei




Re: [PATCH v3 5/6] target/riscv/tcg: add riscv_cpu_write_misa_bit()

2023-10-25 Thread LIU Zhiwei



On 2023/10/21 6:39, Daniel Henrique Barboza wrote:

We have two instances of the setting/clearing a MISA bit from
env->misa_ext and env->misa_ext_mask pattern. And the next patch will
end up adding one more.

Create a helper to avoid code repetition.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
  target/riscv/tcg/tcg-cpu.c | 44 --
  1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 59b75a14ac..ba11d0566d 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -42,6 +42,20 @@ static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
   GUINT_TO_POINTER(ext_offset));
  }
  
+static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t bit,

+ bool enabled)
+{
+CPURISCVState *env = >env;
+
+if (enabled) {
+env->misa_ext |= bit;
+env->misa_ext_mask |= bit;
+} else {
+env->misa_ext &= ~bit;
+env->misa_ext_mask &= ~bit;
+}
+}
+
  static void riscv_cpu_synchronize_from_tb(CPUState *cs,
const TranslationBlock *tb)
  {
@@ -680,20 +694,14 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, 
const char *name,
  return;
  }
  
-if (value) {

-if (!generic_cpu) {
-g_autofree char *cpuname = riscv_cpu_get_name(cpu);
-error_setg(errp, "'%s' CPU does not allow enabling extensions",
-   cpuname);
-return;
-}
-
-env->misa_ext |= misa_bit;
-env->misa_ext_mask |= misa_bit;
-} else {
-env->misa_ext &= ~misa_bit;
-env->misa_ext_mask &= ~misa_bit;
+if (value && !generic_cpu) {
+g_autofree char *cpuname = riscv_cpu_get_name(cpu);
+error_setg(errp, "'%s' CPU does not allow enabling extensions",
+   cpuname);
+return;
  }
+
+riscv_cpu_write_misa_bit(cpu, misa_bit, value);
  }
  
  static void cpu_get_misa_ext_cfg(Object *obj, Visitor *v, const char *name,

@@ -737,7 +745,6 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
   */
  static void riscv_cpu_add_misa_properties(Object *cpu_obj)
  {
-CPURISCVState *env = _CPU(cpu_obj)->env;
  bool use_def_vals = riscv_cpu_is_generic(cpu_obj);
  int i;
  
@@ -758,13 +765,8 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)

  NULL, (void *)misa_cfg);
  object_property_set_description(cpu_obj, name, desc);
  if (use_def_vals) {
-if (misa_cfg->enabled) {
-env->misa_ext |= bit;
-env->misa_ext_mask |= bit;
-} else {
-env->misa_ext &= ~bit;
-env->misa_ext_mask &= ~bit;
-}
+riscv_cpu_write_misa_bit(RISCV_CPU(cpu_obj), bit,
+ misa_cfg->enabled);


Reviewed-by: LIU Zhiwei 

Zhiwei


  }
  }
  }




Re: [PATCH v3 6/6] target/riscv/tcg: handle profile MISA bits

2023-10-25 Thread LIU Zhiwei



On 2023/10/21 6:39, Daniel Henrique Barboza wrote:

The profile support is handling multi-letter extensions only. Let's add
support for MISA bits as well.

We'll go through every known MISA bit. If the user set the bit, doesn't
matter if to 'true' or 'false', ignore it. If the profile doesn't
declare the bit as mandatory, ignore it. Otherwise, set or clear the bit
in env->misa_ext and env->misa_ext_mask depending on whether the profile
was set to 'true' or 'false'.

Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/tcg/tcg-cpu.c | 16 
  1 file changed, 16 insertions(+)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index ba11d0566d..73c7453af6 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -42,6 +42,12 @@ static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
   GUINT_TO_POINTER(ext_offset));
  }
  
+static bool cpu_misa_ext_is_user_set(uint32_t misa_bit)

+{
+return g_hash_table_contains(misa_ext_user_opts,
+ GUINT_TO_POINTER(misa_bit));
+}
+
  static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t bit,
   bool enabled)
  {
@@ -797,6 +803,16 @@ static void cpu_set_profile(Object *obj, Visitor *v, const 
char *name,
  
  profile->enabled = value;
  
+for (i = 0; misa_bits[i] != 0; i++) {

+uint32_t bit = misa_bits[i];
+
+if (cpu_misa_ext_is_user_set(bit) || !(profile->misa_ext & bit)) {
+continue;
+}
+
+riscv_cpu_write_misa_bit(cpu, bit, profile->enabled);
+}
+


Reviewed-by: LIU Zhiwei 

Zhiwei


  for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) {
  ext_offset = profile->ext_offsets[i];
  




Re: [PATCH v3 4/6] target/riscv/tcg: add MISA user options hash

2023-10-25 Thread LIU Zhiwei



On 2023/10/21 6:39, Daniel Henrique Barboza wrote:

We already track user choice for multi-letter extensions because we
needed to honor user choice when enabling/disabling extensions during
realize(). We refrained from adding the same mechanism for MISA
extensions since we didn't need it.

Profile support requires tne need to check for user choice for MISA
extensions, so let's add the corresponding hash now. It works like the
existing multi-letter hash (multi_ext_user_opts) but tracking MISA bits
options in the cpu_set_misa_ext_cfg() callback.

Note that we can't re-use the same hash from multi-letter extensions
because that hash uses cpu->cfg offsets as keys, while for MISA
extensions we're using MISA bits as keys.

After adding the user hash in cpu_set_misa_ext_cfg(), setting default
values with object_property_set_bool() in add_misa_properties() will end
up marking the user choice hash with them. Set the default value
manually to avoid it.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
  target/riscv/tcg/tcg-cpu.c | 15 ++-
  1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 3dd4783191..59b75a14ac 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -34,6 +34,7 @@
  
  /* Hash that stores user set extensions */

  static GHashTable *multi_ext_user_opts;
+static GHashTable *misa_ext_user_opts;
  
  static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)

  {
@@ -669,6 +670,10 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, 
const char *name,
  return;
  }
  
+g_hash_table_insert(misa_ext_user_opts,

+GUINT_TO_POINTER(misa_bit),
+(gpointer)value);
+
  prev_val = env->misa_ext & misa_bit;
  
  if (value == prev_val) {

@@ -732,6 +737,7 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
   */
  static void riscv_cpu_add_misa_properties(Object *cpu_obj)
  {
+CPURISCVState *env = _CPU(cpu_obj)->env;
  bool use_def_vals = riscv_cpu_is_generic(cpu_obj);
  int i;
  
@@ -752,7 +758,13 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)

  NULL, (void *)misa_cfg);
  object_property_set_description(cpu_obj, name, desc);
  if (use_def_vals) {
-object_property_set_bool(cpu_obj, name, misa_cfg->enabled, NULL);
+if (misa_cfg->enabled) {
+env->misa_ext |= bit;
+env->misa_ext_mask |= bit;
+} else {
+env->misa_ext &= ~bit;
+env->misa_ext_mask &= ~bit;
+}
  }
  }
  }
@@ -989,6 +1001,7 @@ static void tcg_cpu_instance_init(CPUState *cs)
  RISCVCPU *cpu = RISCV_CPU(cs);
  Object *obj = OBJECT(cpu);
  
+misa_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);


Reviewed-by: LIU Zhiwei 

Zhiwei


  multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
  riscv_cpu_add_user_properties(obj);
  




Re: [PATCH v3 3/6] target/riscv/tcg: add user flag for profile support

2023-10-25 Thread LIU Zhiwei



On 2023/10/21 6:39, Daniel Henrique Barboza wrote:

The TCG emulation implements all the extensions described in the
RVA22U64 profile, both mandatory and optional. The mandatory extensions
will be enabled via the profile flag. We'll leave the optional
extensions to be enabled by hand.

Given that this is the first profile we're implementing in TCG we'll
need some ground work first:

- all profiles declared in riscv_profiles[] will be exposed to users.
TCG is the main accelerator we're considering when adding profile
support in QEMU, so for now it's safe to assume that all profiles in
riscv_profiles[] will be relevant to TCG;

- we'll not support user profile settings for vendor CPUs. The flags
will still be exposed but users won't be able to change them. The idea
is that vendor CPUs in the future can enable profiles internally in
their cpu_init() functions, showing to the external world that the CPU
supports a certain profile. But users won't be able to enable/disable
it;

- Setting a profile to 'true' means 'enable all mandatory extensions of
this profile, setting it to 'false' means disabling all its mandatory
extensions. Disabling a profile is discouraged for regular use and will
issue an user warning. User choices for individual extensions will take
precedence, i.e. enabling a profile will not enable extensions that the
user set to 'false', and vice-versa. This will make us independent of
left-to-right ordering in the QEMU command line, i.e. the following QEMU
command lines:

-cpu rv64,zicbom=false,rva22u64=true,Zifencei=false
-cpu rv64,zicbom=false,Zifencei=false,rva22u64=true
-cpu rv64,rva22u64=true,zicbom=false,Zifencei=false

They mean the same thing: "enable all mandatory extensions of the
rva22u64 profile while keeping zicbom and Zifencei disabled".

For now we'll handle multi-letter extensions only. MISA extensions need
additional steps that we'll take care later.

Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/tcg/tcg-cpu.c | 59 ++
  1 file changed, 59 insertions(+)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 7a4400e2ba..3dd4783191 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -757,6 +757,63 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
  }
  }
  
+static void cpu_set_profile(Object *obj, Visitor *v, const char *name,

+void *opaque, Error **errp)
+{
+RISCVCPUProfile *profile = opaque;
+RISCVCPU *cpu = RISCV_CPU(obj);
+bool value;
+int i, ext_offset;
+
+if (object_dynamic_cast(obj, TYPE_RISCV_DYNAMIC_CPU) == NULL) {
+error_setg(errp, "Profile %s only available for generic CPUs",
+   profile->name);
+return;
+}
+
+if (!visit_type_bool(v, name, , errp)) {
+return;
+}
+
+if (!value) {
+warn_report("Disabling the '%s' profile is a debug/development "
+"tool, not recommended for regular use",
+profile->name);
+}
+
+profile->enabled = value;
+
+for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) {
+ext_offset = profile->ext_offsets[i];
+
+if (cpu_cfg_ext_is_user_set(ext_offset)) {
+continue;
+}
+
+isa_ext_update_enabled(cpu, ext_offset, profile->enabled);
+}
+}
+
+static void cpu_get_profile(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+RISCVCPUProfile *profile = opaque;
+bool value = profile->enabled;
+
+visit_type_bool(v, name, , errp);
+}
+
+static void riscv_cpu_add_profiles(Object *cpu_obj)
+{
+for (int i = 0; riscv_profiles[i] != NULL; i++) {
+const RISCVCPUProfile *profile = riscv_profiles[i];
+
+object_property_add(cpu_obj, profile->name, "bool",
+cpu_get_profile, cpu_set_profile,
+NULL, (void *)profile);
+}
+}
+
  static bool cpu_ext_is_deprecated(const char *ext_name)
  {
  return isupper(ext_name[0]);
@@ -880,6 +937,8 @@ static void riscv_cpu_add_user_properties(Object *obj)
  
  riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_deprecated_exts);
  
+riscv_cpu_add_profiles(obj);

+


Acked-by: LIU Zhiwei 

Zhiwei


  for (Property *prop = riscv_cpu_options; prop && prop->name; prop++) {
  qdev_property_add_static(DEVICE(obj), prop);
  }




Re: [PATCH v3 2/6] target/riscv/kvm: add 'rva22u64' flag as unavailable

2023-10-25 Thread LIU Zhiwei



On 2023/10/21 6:39, Daniel Henrique Barboza wrote:

KVM does not have the means to support enabling the rva22u64 profile.
The main reasons are:

- we're missing support for some mandatory rva22u64 extensions in the
   KVM module;

- we can't make promises about enabling a profile since it all depends
   on host support in the end.

We'll revisit this decision in the future if needed. For now mark the
'rva22u64' profile as unavailable when running a KVM CPU:

$ qemu-system-riscv64 -machine virt,accel=kvm -cpu rv64,rva22u64=true
qemu-system-riscv64: can't apply global rv64-riscv-cpu.rva22u64=true:
 'rva22u64' is not available with KVM

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
  target/riscv/kvm/kvm-cpu.c | 7 ++-
  1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 5246fc2bdc..dc14c54ce4 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -360,7 +360,7 @@ static void cpu_set_cfg_unavailable(Object *obj, Visitor *v,
  }
  
  if (value) {

-error_setg(errp, "extension %s is not available with KVM",
+error_setg(errp, "'%s' is not available with KVM",
 propname);
  }
  }
@@ -440,6 +440,11 @@ static void kvm_riscv_add_cpu_user_properties(Object 
*cpu_obj)
  riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, riscv_cpu_extensions);
  riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, riscv_cpu_vendor_exts);
  riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, 
riscv_cpu_experimental_exts);
+
+   /* We don't have the needed KVM support for profiles */
+for (i = 0; riscv_profiles[i] != NULL; i++) {
+riscv_cpu_add_kvm_unavail_prop(cpu_obj, riscv_profiles[i]->name);
+    }


Reviewed-by: LIU Zhiwei 

Zhiwei


  }
  
  static int kvm_riscv_get_regs_core(CPUState *cs)




Re: [PATCH v3 1/6] target/riscv: add rva22u64 profile definition

2023-10-25 Thread LIU Zhiwei



On 2023/10/21 6:39, Daniel Henrique Barboza wrote:

The rva22U64 profile, described in:

https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc#rva22-profiles

Contains a set of CPU extensions aimed for 64-bit userspace
applications. Enabling this set to be enabled via a single user flag
makes it convenient to enable a predictable set of features for the CPU,
giving users more predicability when running/testing their workloads.

QEMU implements all possible extensions of this profile. The exception
is Zicbop (Cache-Block Prefetch Operations) that is not available since
QEMU RISC-V does not implement a cache model. For this same reason all
the so called 'synthetic extensions' described in the profile that are
cache related are ignored (Za64rs, Zic64b, Ziccif, Ziccrse, Ziccamoa,
Zicclsm).

An abstraction called RISCVCPUProfile is created to store the profile.
'ext_offsets' contains mandatory extensions that QEMU supports. Same
thing with the 'misa_ext' mask. Optional extensions must be enabled
manually in the command line if desired.

The design here is to use the common target/riscv/cpu.c file to store
the profile declaration and export it to the accelerator files. Each
accelerator is then responsible to expose it (or not) to users and how
to enable the extensions.

Next patches will implement the profile for TCG and KVM.

Signed-off-by: Daniel Henrique Barboza 
Acked-by: Alistair Francis 
---
  target/riscv/cpu.c | 20 
  target/riscv/cpu.h | 12 
  2 files changed, 32 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c64cd726f4..1b75b506c4 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1397,6 +1397,26 @@ Property riscv_cpu_options[] = {
  DEFINE_PROP_END_OF_LIST(),
  };
  
+/* Optional extensions left out: RVV, zfh, zkn, zks */

+static RISCVCPUProfile RVA22U64 = {
+.name = "rva22u64",
+.misa_ext = RVM | RVA | RVF | RVD | RVC,


Why not include RVI?

Zhiwei


+.ext_offsets = {
+CPU_CFG_OFFSET(ext_zicsr), CPU_CFG_OFFSET(ext_zihintpause),
+CPU_CFG_OFFSET(ext_zba), CPU_CFG_OFFSET(ext_zbb),
+CPU_CFG_OFFSET(ext_zbs), CPU_CFG_OFFSET(ext_zfhmin),
+CPU_CFG_OFFSET(ext_zkt), CPU_CFG_OFFSET(ext_zicntr),
+CPU_CFG_OFFSET(ext_zihpm), CPU_CFG_OFFSET(ext_zicbom),
+CPU_CFG_OFFSET(ext_zicboz),
+
+RISCV_PROFILE_EXT_LIST_END
+}
+};
+
+RISCVCPUProfile *riscv_profiles[] = {
+, NULL,
+};
+
  static Property riscv_cpu_properties[] = {
  DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
  
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h

index 7f61e17202..53c1970e0a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -66,6 +66,18 @@ const char *riscv_get_misa_ext_description(uint32_t bit);
  
  #define CPU_CFG_OFFSET(_prop) offsetof(struct RISCVCPUConfig, _prop)
  
+typedef struct riscv_cpu_profile {

+const char *name;
+uint32_t misa_ext;
+bool enabled;
+bool user_set;
+const int32_t ext_offsets[];
+} RISCVCPUProfile;
+
+#define RISCV_PROFILE_EXT_LIST_END -1
+
+extern RISCVCPUProfile *riscv_profiles[];
+
  /* Privileged specification version */
  enum {
  PRIV_VERSION_1_10_0 = 0,




Re: [PATCH 0/6] hw/ppc: SysBus simplifications

2023-10-19 Thread LIU Zhiwei



On 2023/10/18 21:30, Philippe Mathieu-Daudé wrote:

Hi,

There is no point in exposing an internal MMIO region via
SysBus and directly mapping it in the very same device.

This series replaces a sequence of:
- sysbus_init_mmio()
- sysbus_mmio_map()
by a single call to memory_region_add_subregion().


Reviewed-by: LIU Zhiwei 

Zhiwei



Philippe Mathieu-Daudé (6):
   hw/ppc/pnv_xscom: Rename pnv_xscom_realize(Error **) ->
 pnv_xscom_init()
   hw/ppc/pnv_xscom: Move sysbus_mmio_map() call within pnv_xscom_init()
   hw/ppc/pnv_xscom: Do not use SysBus API to map local MMIO region
   hw/ppc/pnv: Do not use SysBus API to map local MMIO region
   hw/intc/spapr_xive: Move sysbus_init_mmio() calls around
   hw/intc/spapr_xive: Do not use SysBus API to map local MMIO region

  include/hw/ppc/pnv_xscom.h |  2 +-
  hw/intc/spapr_xive.c   | 12 ++--
  hw/ppc/pnv.c   | 26 +-
  hw/ppc/pnv_xscom.c |  5 ++---
  4 files changed, 14 insertions(+), 31 deletions(-)





Re: [PATCH v4 3/5] target/riscv: Move misa_mxl_max to class

2023-10-18 Thread LIU Zhiwei



On 2023/10/18 2:53, Akihiko Odaki wrote:

misa_mxl_max is common for all instances of a RISC-V CPU class so they
are better put into class.

Signed-off-by: Akihiko Odaki 
---
  target/riscv/cpu-qom.h |   1 +
  target/riscv/cpu.h |   3 +-
  hw/riscv/boot.c|   2 +-
  target/riscv/cpu.c | 118 +++--
  target/riscv/gdbstub.c |  12 ++--
  target/riscv/kvm/kvm-cpu.c |  10 ++--
  target/riscv/machine.c |   7 +--
  target/riscv/tcg/tcg-cpu.c |  12 ++--
  target/riscv/translate.c   |   3 +-
  9 files changed, 88 insertions(+), 80 deletions(-)

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index f3fbe37a2c..33b6d52c90 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -68,5 +68,6 @@ struct RISCVCPUClass {
  /*< public >*/
  DeviceRealize parent_realize;
  ResettablePhases parent_phases;
+uint32_t misa_mxl_max;  /* max mxl for this cpu */
  };
  #endif /* RISCV_CPU_QOM_H */
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index f8ffa5ee38..ef10efd1e7 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -159,7 +159,6 @@ struct CPUArchState {
  
  /* RISCVMXL, but uint32_t for vmstate migration */

  uint32_t misa_mxl;  /* current mxl */
-uint32_t misa_mxl_max;  /* max mxl for this cpu */
  uint32_t misa_ext;  /* current extensions */
  uint32_t misa_ext_mask; /* max ext for this cpu */
  uint32_t xl;/* current xlen */
@@ -711,7 +710,7 @@ enum riscv_pmu_event_idx {
  /* used by tcg/tcg-cpu.c*/
  void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t ext_offset, bool en);
  bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset);
-void riscv_cpu_set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext);
+void riscv_cpu_set_misa_ext(CPURISCVState *env, uint32_t ext);
  
  typedef struct RISCVCPUMultiExtConfig {

  const char *name;
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 52bf8e67de..b7cf08f479 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -36,7 +36,7 @@
  
  bool riscv_is_32bit(RISCVHartArrayState *harts)

  {
-return harts->harts[0].env.misa_mxl_max == MXL_RV32;
+return RISCV_CPU_GET_CLASS(>harts[0])->misa_mxl_max == MXL_RV32;


Hi Akihiko,

Can we use the cached CPUClass  in CPUState?  Like

(RISCVCPUClass *)((CPUState *)(>harts[0])->cc)


Zhiwei


  }
  
  /*

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ac4a6c7eec..1fb5747f00 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -263,9 +263,8 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, 
bool async)
  }
  }
  
-void riscv_cpu_set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)

+void riscv_cpu_set_misa_ext(CPURISCVState *env, uint32_t ext)
  {
-env->misa_mxl_max = env->misa_mxl = mxl;
  env->misa_ext_mask = env->misa_ext = ext;
  }
  
@@ -367,11 +366,7 @@ static void riscv_any_cpu_init(Object *obj)

  {
  RISCVCPU *cpu = RISCV_CPU(obj);
  CPURISCVState *env = >env;
-#if defined(TARGET_RISCV32)
-riscv_cpu_set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
-#elif defined(TARGET_RISCV64)
-riscv_cpu_set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
-#endif
+riscv_cpu_set_misa_ext(env, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
  
  #ifndef CONFIG_USER_ONLY

  set_satp_mode_max_supported(RISCV_CPU(obj),
@@ -392,16 +387,14 @@ static void riscv_max_cpu_init(Object *obj)
  {
  RISCVCPU *cpu = RISCV_CPU(obj);
  CPURISCVState *env = >env;
-RISCVMXL mlx = MXL_RV64;
  
-#ifdef TARGET_RISCV32

-mlx = MXL_RV32;
-#endif
-riscv_cpu_set_misa(env, mlx, 0);
  env->priv_ver = PRIV_VERSION_LATEST;
  #ifndef CONFIG_USER_ONLY
-set_satp_mode_max_supported(RISCV_CPU(obj), mlx == MXL_RV32 ?
-VM_1_10_SV32 : VM_1_10_SV57);
+#ifdef TARGET_RISCV32
+set_satp_mode_max_supported(cpu, VM_1_10_SV32);
+#else
+set_satp_mode_max_supported(cpu, VM_1_10_SV57);
+#endif
  #endif
  }
  
@@ -409,8 +402,6 @@ static void riscv_max_cpu_init(Object *obj)

  static void rv64_base_cpu_init(Object *obj)
  {
  CPURISCVState *env = _CPU(obj)->env;
-/* We set this in the realise function */
-riscv_cpu_set_misa(env, MXL_RV64, 0);
  /* Set latest version of privileged specification */
  env->priv_ver = PRIV_VERSION_LATEST;
  #ifndef CONFIG_USER_ONLY
@@ -422,8 +413,7 @@ static void rv64_sifive_u_cpu_init(Object *obj)
  {
  RISCVCPU *cpu = RISCV_CPU(obj);
  CPURISCVState *env = >env;
-riscv_cpu_set_misa(env, MXL_RV64,
-   RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+riscv_cpu_set_misa_ext(env, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
  env->priv_ver = PRIV_VERSION_1_10_0;
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
@@ -441,7 +431,7 @@ static void rv64_sifive_e_cpu_init(Object *obj)
  CPURISCVState *env = _CPU(obj)->env;
  

Re: [PATCH v4 2/5] target/riscv: Remove misa_mxl validation

2023-10-17 Thread LIU Zhiwei



On 2023/10/18 2:53, Akihiko Odaki wrote:

It is initialized with a simple assignment and there is little room for
error. In fact, the validation is even more complex.

Signed-off-by: Akihiko Odaki 
---
  target/riscv/tcg/tcg-cpu.c | 13 ++---
  1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index a28918ab30..7f45e42000 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -148,7 +148,7 @@ static void riscv_cpu_validate_misa_priv(CPURISCVState 
*env, Error **errp)
  }
  }
  
-static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)

+static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu)
  {
  RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
  CPUClass *cc = CPU_CLASS(mcc);
@@ -168,11 +168,6 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, 
Error **errp)
  default:
  g_assert_not_reached();
  }
-
-if (env->misa_mxl_max != env->misa_mxl) {
-error_setg(errp, "misa_mxl_max must be equal to misa_mxl");
-return;
-}
  }
  
  static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp)

@@ -573,11 +568,7 @@ static bool tcg_cpu_realize(CPUState *cs, Error **errp)
  return false;
  }
  
-riscv_cpu_validate_misa_mxl(cpu, _err);

-if (local_err != NULL) {
-error_propagate(errp, local_err);
-return false;
-}
+riscv_cpu_validate_misa_mxl(cpu);


Acked-by: LIU Zhiwei 

Zhiwei

  
  riscv_cpu_validate_priv_spec(cpu, _err);

  if (local_err != NULL) {




Re: [PATCH 1/4] target/riscv: Remove misa_mxl validation

2023-10-17 Thread LIU Zhiwei

+CC Richard

On 2023/10/17 11:37, Akihiko Odaki wrote:

On 2023/10/17 11:29, LIU Zhiwei wrote:


On 2023/10/12 13:42, Akihiko Odaki wrote:

It is initialized with a simple assignment and there is little room for
error. In fact, the validation is even more complex.

Signed-off-by: Akihiko Odaki 
---
  target/riscv/cpu.c | 13 ++---
  1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index f5572704de..550b357fb7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1042,7 +1042,7 @@ static void 
riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)

  }
  }
-static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
+static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu)
  {
  RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
  CPUClass *cc = CPU_CLASS(mcc);
@@ -1062,11 +1062,6 @@ static void 
riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)

  default:
  g_assert_not_reached();
  }
-
-    if (env->misa_mxl_max != env->misa_mxl) {
-    error_setg(errp, "misa_mxl_max must be equal to misa_mxl");
-    return;
-    }
  }
  /*
@@ -1447,11 +1442,7 @@ static void riscv_cpu_realize_tcg(DeviceState 
*dev, Error **errp)

  return;
  }
-    riscv_cpu_validate_misa_mxl(cpu, _err);
-    if (local_err != NULL) {
-    error_propagate(errp, local_err);
-    return;
-    }
+    riscv_cpu_validate_misa_mxl(cpu);


This it not right.  As we are still working on the supporting for 
MXL32 or SXL32, this validation is needed.


It's not preventing supporting MXL32 or SXL32. It's removing 
env->misa_mxl_max != env->misa_mxl just because it's initialized with 
a simple statement:

env->misa_mxl_max = env->misa_mxl = mxl;

It makes little sense to have a validation code that is more complex 
than the validated code.




And we can't ensure the all RISC-V cpus have the same misa_mxl_max or 
misa_mxl,   it is not right to move it to class.
For example, in the future, riscv64-softmmu can run 32-bit cpu and 
64-bit cpu. And maybe in heterogeneous SOC,

we have 32-bit cpu and 64-bit cpu together.


This patch series does not touch misa_mxl. We don't need to ensure 
that all CPUs have the same misa_mxl_max, but we just need to ensure 
that CPUs in the same class do. Creating a heterogeneous SoC is still 
possible by combining e.g. TYPE_RISCV_CPU_SIFIVE_E31 and 
TYPE_RISCV_CPU_SIFIVE_E51, for example.


I see what you mean. It makes sense  to move the misa_mxl_max field from 
env to the class struct. The misa_mxl_max  is always be set by  cpu init 
or the migration.


The former  is OK. I don't know whether QEMU supports migration from 
32-bit CPU to 64-bit CPU. Otherwise,


Acked-by: LIU Zhiwei 

Zhiwei




Re: [PATCH v2 1/3] target/riscv: Do not allow MXL_RV32 for TARGET_RISCV64

2023-10-16 Thread LIU Zhiwei



On 2023/10/17 11:32, Alistair Francis wrote:

On Tue, Oct 17, 2023 at 12:14 PM LIU Zhiwei
 wrote:


On 2023/10/16 9:51, Alistair Francis wrote:

On Sun, Oct 15, 2023 at 4:05 AM Daniel Henrique Barboza
 wrote:


On 10/14/23 00:35, Akihiko Odaki wrote:

TARGET_RISCV64 does not have riscv-32bit-cpu.xml so it shouldn't accept
MXL_RV32.

Signed-off-by: Akihiko Odaki 
---

Reviewed-by: Daniel Henrique Barboza 



target/riscv/tcg/tcg-cpu.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index a28918ab30..e0cbc56320 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -161,10 +161,11 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, 
Error **errp)
case MXL_RV128:
cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
break;
-#endif
+#elif defined(TARGET_RISCV32)
case MXL_RV32:
cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
break;
+#endif

This isn't the right fix. The idea is that riscv64-softmmu can run
32-bit CPUs, so we instead should include riscv-32bit-cpu.xml

Agree. I'd like to go on the work. The question is that we don't have
64-bit OpenSBI which supports booting 32-bit Linux.
So even we have implemented the SXLEN 32bit, we may not have the
software to test it.

Ah! So I was first talking around just a full 32-bit CPU.

So for example:
 qemu-system-riscv64 -machine opentitan

So we are using qemu-system-riscv64 to run a 32-bit only CPU.


Yes, if the 32-bit only cpu only has M mode, it can work now.

I have tried this for Xuantie E series cpu, for example the e902,  in 
the wild tree.




Then we can think about SXLEN


Agree, maybe we can expose these cpus now.

Thanks,
Zhiwei




Do you support the SXL upstreaming with no testing?

No, it should be tested

Alistair


Thanks,
Zhiwei


Alistair


default:
g_assert_not_reached();
}




Re: [PATCH 1/4] target/riscv: Remove misa_mxl validation

2023-10-16 Thread LIU Zhiwei



On 2023/10/12 13:42, Akihiko Odaki wrote:

It is initialized with a simple assignment and there is little room for
error. In fact, the validation is even more complex.

Signed-off-by: Akihiko Odaki 
---
  target/riscv/cpu.c | 13 ++---
  1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index f5572704de..550b357fb7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1042,7 +1042,7 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU 
*cpu)
  }
  }
  
-static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)

+static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu)
  {
  RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
  CPUClass *cc = CPU_CLASS(mcc);
@@ -1062,11 +1062,6 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, 
Error **errp)
  default:
  g_assert_not_reached();
  }
-
-if (env->misa_mxl_max != env->misa_mxl) {
-error_setg(errp, "misa_mxl_max must be equal to misa_mxl");
-return;
-}
  }
  
  /*

@@ -1447,11 +1442,7 @@ static void riscv_cpu_realize_tcg(DeviceState *dev, 
Error **errp)
  return;
  }
  
-riscv_cpu_validate_misa_mxl(cpu, _err);

-if (local_err != NULL) {
-error_propagate(errp, local_err);
-return;
-}
+riscv_cpu_validate_misa_mxl(cpu);


This it not right.  As we are still working on the supporting for MXL32 
or SXL32, this validation is needed.


And we can't ensure the all RISC-V cpus have the same misa_mxl_max or 
misa_mxl,   it is not right to move it to class.
For example, in the future, riscv64-softmmu can run 32-bit cpu and 
64-bit cpu. And maybe in heterogeneous SOC,

we have 32-bit cpu and 64-bit cpu together.

I am afraid that we can not accept this patch set.

Thanks,
Zhiwei

  
  riscv_cpu_validate_priv_spec(cpu, _err);

  if (local_err != NULL) {




Re: [PATCH v2 1/3] target/riscv: Do not allow MXL_RV32 for TARGET_RISCV64

2023-10-16 Thread LIU Zhiwei



On 2023/10/16 9:51, Alistair Francis wrote:

On Sun, Oct 15, 2023 at 4:05 AM Daniel Henrique Barboza
 wrote:



On 10/14/23 00:35, Akihiko Odaki wrote:

TARGET_RISCV64 does not have riscv-32bit-cpu.xml so it shouldn't accept
MXL_RV32.

Signed-off-by: Akihiko Odaki 
---

Reviewed-by: Daniel Henrique Barboza 



   target/riscv/tcg/tcg-cpu.c | 3 ++-
   1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index a28918ab30..e0cbc56320 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -161,10 +161,11 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, 
Error **errp)
   case MXL_RV128:
   cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
   break;
-#endif
+#elif defined(TARGET_RISCV32)
   case MXL_RV32:
   cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
   break;
+#endif

This isn't the right fix. The idea is that riscv64-softmmu can run
32-bit CPUs, so we instead should include riscv-32bit-cpu.xml


Agree. I'd like to go on the work. The question is that we don't have 
64-bit OpenSBI which supports booting 32-bit Linux.
So even we have implemented the SXLEN 32bit, we may not have the 
software to test it.


Do you support the SXL upstreaming with no testing?

Thanks,
Zhiwei



Alistair


   default:
   g_assert_not_reached();
   }




Re: [PATCH 2/6] target/riscv: Use env_archcpu() in [check_]nanbox()

2023-10-13 Thread LIU Zhiwei



On 2023/10/13 0:06, Richard Henderson wrote:

On 10/11/23 22:59, LIU Zhiwei wrote:


On 2023/10/11 13:31, Philippe Mathieu-Daudé wrote:

On 11/10/23 05:25, LIU Zhiwei wrote:


On 2023/10/11 1:04, Richard Henderson wrote:

On 10/9/23 05:42, LIU Zhiwei wrote:


On 2023/10/9 19:02, Philippe Mathieu-Daudé wrote:

When CPUArchState* is available (here CPURISCVState*), we
can use the fast env_archcpu() macro to get ArchCPU* (here
RISCVCPU*). The QOM cast RISCV_CPU() macro will be slower
when building with --enable-qom-cast-debug.




If so, maybe we have to do this qom cast somewhere.


No, I don't think so.  Or at least not in these places.


Yes.  Perhaps, we should remove all RISCV_CPU macros using after 
the qom objects realized.


Do you think we should remove the RISCV_CPU using in 
riscv_cpu_exec_interrupt? Although it  is not so hot. I think there 
is no reason to use it there.


I have some note in my TODO to check replacing CPUState by ArchCPU in
TCGCPUOps (like the cpu_exec_interrupt handler you mentioned). 


IMHO, this will make it harder for heterogeneous SOC support. ArchCPU 
is not a target agnostic struct.


ArchCPU is a target-agnostic typedef of a structure with no visible 
definition.

C is perfectly happy to manipulate pointers to such structures.


Get it. Thanks
Whether it is worthwhile to adjust interfaces from CPUState to 
ArchCPU, I don't know.


OK. Let's just wait for a good reason to do that.

Zhiwei




r~




Re: [PATCH v2 5/6] target/riscv: Add "pmu-mask" property to replace "pmu-num"

2023-10-12 Thread LIU Zhiwei



On 2023/10/12 20:38, Rob Bradford wrote:

On Thu, 2023-10-12 at 17:05 +0800, LIU Zhiwei wrote:
  

  
  
On 2023/10/11 22:45, Rob Bradford wrote:
  
  
  
Using a mask instead of the number of PMU devices supports the

accurate
emulation of platforms that have a discontinuous set of PMU
counters.

Generate a warning if the old property changed from the default but
still go ahead and use it to generate the mask if the user has
changed
it from the default

Signed-off-by: Rob Bradford 
---
  target/riscv/cpu.c |  5 +++--
  target/riscv/cpu_cfg.h |  3 ++-
  target/riscv/machine.c |  2 +-
  target/riscv/pmu.c | 14 ++
  4 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c9d8fc12fe..4d2987e568 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1487,7 +1487,7 @@ static void riscv_cpu_realize_tcg(DeviceState
*dev, Error **errp)
  riscv_timer_init(cpu);
  }
  
-if (cpu->cfg.pmu_num) {

+if (cpu->cfg.pmu_mask) {
  riscv_pmu_init(cpu, _err);
  if (local_err != NULL) {
  error_propagate(errp, local_err);
@@ -1812,7 +1812,8 @@ static void
riscv_cpu_add_misa_properties(Object *cpu_obj)
  
  static Property riscv_cpu_extensions[] = {

  /* Defaults for standard extensions */
-DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
+DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16), /*
Deprecated */
+DEFINE_PROP_UINT32("pmu-mask", RISCVCPU, cfg.pmu_mask,
MAKE_32BIT_MASK(3, 16)),
  DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf,
false),
  DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
  DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 0e6a0f245c..d273487040 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -123,7 +123,8 @@ struct RISCVCPUConfig {
  bool ext_xtheadsync;
  bool ext_XVentanaCondOps;
  
-uint8_t pmu_num;

+uint8_t pmu_num; /* Deprecated */
+uint32_t pmu_mask;
  char *priv_spec;
  char *user_spec;
  char *bext_spec;
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index c7c862cdd3..9f6e3f7a6d 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -313,7 +313,7 @@ static bool pmu_needed(void *opaque)
  {
  RISCVCPU *cpu = opaque;
  
-return cpu->cfg.pmu_num;

+return (cpu->cfg.pmu_mask > 0);
  }
  
  static const VMStateDescription vmstate_pmu_ctr_state = {

diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index 360c76f63e..f2d35b4d3b 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -18,6 +18,7 @@
  
  #include "qemu/osdep.h"

  #include "qemu/log.h"
+#include "qemu/error-report.h"
  #include "cpu.h"
  #include "pmu.h"
  #include "sysemu/cpu-timers.h"
@@ -182,7 +183,7 @@ int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum
riscv_pmu_event_idx event_idx)
  CPURISCVState *env = >env;
  gpointer value;
  
-if (!cpu->cfg.pmu_num) {

+if (!cpu->cfg.pmu_mask) {
  return 0;
  }
  value = g_hash_table_lookup(cpu->pmu_event_ctr_map,
@@ -432,7 +433,7 @@ void riscv_pmu_init(RISCVCPU *cpu, Error
**errp)
  {
  uint8_t pmu_num = cpu->cfg.pmu_num;
  
-if (pmu_num > (RV_MAX_MHPMCOUNTERS - 3)) {

+if (ctpop32(cpu->cfg.pmu_mask) > (RV_MAX_MHPMCOUNTERS - 3)) {
  
  
  
  
  error_setg(errp, "Number of counters exceeds maximum

available");
  return;
  }
@@ -443,6 +444,11 @@ void riscv_pmu_init(RISCVCPU *cpu, Error
**errp)
  return;
  }
  
-/* Create a bitmask of available programmable counters */

-cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, pmu_num);
+/* Check if user set it by comparing against default */
+if (pmu_num != 16) {
+warn_report("\"pmu-num\" property is deprecated; use
\"pmu-mask\"");
+cpu->cfg.pmu_mask = MAKE_32BIT_MASK(3, pmu_num);
+}
+
+cpu->pmu_avail_ctrs = cpu->cfg.pmu_mask;
  
  
How to process the pmu_mask[0:2] no-zero bits? They should not

included into pmu_avail_ctrs.
  

Good point, thanks Zhiwei. I think rather than masking those bits it is
better to add a check and error out if those bits are set.


Agree.

Thanks,
Zhiwei



Cheers,

Rob


Zhiwei
  
  
  
  }
  
  




Re: [PATCH v2 6/6] docs/about/deprecated: Document RISC-V "pmu-num" deprecation

2023-10-12 Thread LIU Zhiwei



On 2023/10/11 22:45, Rob Bradford wrote:

This has been replaced by a "pmu-mask" property that provides much more
flexibility.

Signed-off-by: Rob Bradford 
---
  docs/about/deprecated.rst | 10 ++
  1 file changed, 10 insertions(+)

diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 8b136320e2..37f3414ef8 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -361,6 +361,16 @@ Specifying the iSCSI password in plain text on the command 
line using the
  used instead, to refer to a ``--object secret...`` instance that provides
  a password via a file, or encrypted.
  
+CPU device properties

+'
+
+``pmu-num=x`` on RISC-V CPUs (since 8.2)
+
+
+In order to support more flexible counter configurations this has been
+replaced by a ``pmu-mask`` property
+
+


Acked-by: LIU Zhiwei 

Zhiwei


  Backwards compatibility
  ---
  




Re: [PATCH v2 5/6] target/riscv: Add "pmu-mask" property to replace "pmu-num"

2023-10-12 Thread LIU Zhiwei


On 2023/10/11 22:45, Rob Bradford wrote:

Using a mask instead of the number of PMU devices supports the accurate
emulation of platforms that have a discontinuous set of PMU counters.

Generate a warning if the old property changed from the default but
still go ahead and use it to generate the mask if the user has changed
it from the default

Signed-off-by: Rob Bradford
---
  target/riscv/cpu.c |  5 +++--
  target/riscv/cpu_cfg.h |  3 ++-
  target/riscv/machine.c |  2 +-
  target/riscv/pmu.c | 14 ++
  4 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c9d8fc12fe..4d2987e568 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1487,7 +1487,7 @@ static void riscv_cpu_realize_tcg(DeviceState *dev, Error 
**errp)
  riscv_timer_init(cpu);
  }
  
-if (cpu->cfg.pmu_num) {

+if (cpu->cfg.pmu_mask) {
  riscv_pmu_init(cpu, _err);
  if (local_err != NULL) {
  error_propagate(errp, local_err);
@@ -1812,7 +1812,8 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
  
  static Property riscv_cpu_extensions[] = {

  /* Defaults for standard extensions */
-DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
+DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16), /* Deprecated */
+DEFINE_PROP_UINT32("pmu-mask", RISCVCPU, cfg.pmu_mask, MAKE_32BIT_MASK(3, 
16)),
  DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
  DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
  DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 0e6a0f245c..d273487040 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -123,7 +123,8 @@ struct RISCVCPUConfig {
  bool ext_xtheadsync;
  bool ext_XVentanaCondOps;
  
-uint8_t pmu_num;

+uint8_t pmu_num; /* Deprecated */
+uint32_t pmu_mask;
  char *priv_spec;
  char *user_spec;
  char *bext_spec;
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index c7c862cdd3..9f6e3f7a6d 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -313,7 +313,7 @@ static bool pmu_needed(void *opaque)
  {
  RISCVCPU *cpu = opaque;
  
-return cpu->cfg.pmu_num;

+return (cpu->cfg.pmu_mask > 0);
  }
  
  static const VMStateDescription vmstate_pmu_ctr_state = {

diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index 360c76f63e..f2d35b4d3b 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -18,6 +18,7 @@
  
  #include "qemu/osdep.h"

  #include "qemu/log.h"
+#include "qemu/error-report.h"
  #include "cpu.h"
  #include "pmu.h"
  #include "sysemu/cpu-timers.h"
@@ -182,7 +183,7 @@ int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum 
riscv_pmu_event_idx event_idx)
  CPURISCVState *env = >env;
  gpointer value;
  
-if (!cpu->cfg.pmu_num) {

+if (!cpu->cfg.pmu_mask) {
  return 0;
  }
  value = g_hash_table_lookup(cpu->pmu_event_ctr_map,
@@ -432,7 +433,7 @@ void riscv_pmu_init(RISCVCPU *cpu, Error **errp)
  {
  uint8_t pmu_num = cpu->cfg.pmu_num;
  
-if (pmu_num > (RV_MAX_MHPMCOUNTERS - 3)) {

+if (ctpop32(cpu->cfg.pmu_mask) > (RV_MAX_MHPMCOUNTERS - 3)) {
  error_setg(errp, "Number of counters exceeds maximum available");
  return;
  }
@@ -443,6 +444,11 @@ void riscv_pmu_init(RISCVCPU *cpu, Error **errp)
  return;
  }
  
-/* Create a bitmask of available programmable counters */

-cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, pmu_num);
+/* Check if user set it by comparing against default */
+if (pmu_num != 16) {
+warn_report("\"pmu-num\" property is deprecated; use \"pmu-mask\"");
+cpu->cfg.pmu_mask = MAKE_32BIT_MASK(3, pmu_num);
+}
+
+cpu->pmu_avail_ctrs = cpu->cfg.pmu_mask;


How to process the pmu_mask[0:2] no-zero bits? They should not included 
into pmu_avail_ctrs.


Zhiwei


  }

Re: [PATCH v2 4/6] qemu/bitops.h: Add MAKE_32BIT_MASK macro

2023-10-12 Thread LIU Zhiwei



On 2023/10/11 22:45, Rob Bradford wrote:

Add 32-bit version of mask generating macro and use it in the RISC-V PMU
code.

CC Richard

Signed-off-by: Rob Bradford 
---
  include/qemu/bitops.h | 3 +++
  target/riscv/pmu.c| 2 --
  2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h
index cb3526d1f4..9b25b2d5e4 100644
--- a/include/qemu/bitops.h
+++ b/include/qemu/bitops.h
@@ -25,6 +25,9 @@
  #define BIT_WORD(nr)((nr) / BITS_PER_LONG)
  #define BITS_TO_LONGS(nr)   DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
  
+#define MAKE_32BIT_MASK(shift, length) \

+(((uint32_t)(~0UL) >> (32 - (length))) << (shift))
+
  #define MAKE_64BIT_MASK(shift, length) \
  (((~0ULL) >> (64 - (length))) << (shift))
  
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c

index 7ddf4977b1..360c76f63e 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -24,8 +24,6 @@
  #include "sysemu/device_tree.h"
  
  #define RISCV_TIMEBASE_FREQ 10 /* 1Ghz */

-#define MAKE_32BIT_MASK(shift, length) \
-(((uint32_t)(~0UL) >> (32 - (length))) << (shift))
  


We can always use the MAKE_64BIT_MASK instead of MAKE_32BIT_MASK.  And 
MAKE_32BIT_MASK only used in target/riscv. I am not sure  whether this 
patch will be accepted.


Acked-by: LIU Zhiwei 

Zhiwei


  /*
   * To keep it simple, any event can be mapped to any programmable counters in




Re: [PATCH v2 3/6] target/riscv: Use existing PMU counter mask in FDT generation

2023-10-12 Thread LIU Zhiwei



On 2023/10/11 22:45, Rob Bradford wrote:

During the FDT generation use the existing mask containing the enabled
counters rather then generating a new one. Using the existing mask will
support the use of discontinuous counters.

Signed-off-by: Rob Bradford 
---
  hw/riscv/virt.c| 2 +-
  target/riscv/pmu.c | 6 +-
  target/riscv/pmu.h | 2 +-
  3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 5edc1d98d2..acdbaf9da5 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -722,7 +722,7 @@ static void create_fdt_pmu(RISCVVirtState *s)
  pmu_name = g_strdup_printf("/pmu");
  qemu_fdt_add_subnode(ms->fdt, pmu_name);
  qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu");
-riscv_pmu_generate_fdt_node(ms->fdt, hart.cfg.pmu_num, pmu_name);
+riscv_pmu_generate_fdt_node(ms->fdt, hart.pmu_avail_ctrs, pmu_name);
  
  g_free(pmu_name);

  }
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index 13801ccb78..7ddf4977b1 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -34,13 +34,9 @@
   * to provide the correct value as well. Heterogeneous PMU per hart is not
   * supported yet. Thus, number of counters are same across all harts.
   */
-void riscv_pmu_generate_fdt_node(void *fdt, int num_ctrs, char *pmu_name)
+void riscv_pmu_generate_fdt_node(void *fdt, uint32_t cmask, char *pmu_name)
  {
  uint32_t fdt_event_ctr_map[15] = {};
-uint32_t cmask;
-
-/* All the programmable counters can map to any event */
-cmask = MAKE_32BIT_MASK(3, num_ctrs);
  
 /*

  * The event encoding is specified in the SBI specification
diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
index 88e0713296..505fc850d3 100644
--- a/target/riscv/pmu.h
+++ b/target/riscv/pmu.h
@@ -28,6 +28,6 @@ void riscv_pmu_init(RISCVCPU *cpu, Error **errp);
  int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
 uint32_t ctr_idx);
  int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx);
-void riscv_pmu_generate_fdt_node(void *fdt, int num_counters, char *pmu_name);
+void riscv_pmu_generate_fdt_node(void *fdt, uint32_t cmask, char *pmu_name);


Reviewed-by: LIU Zhiwei 

Zhiwei


  int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value,
uint32_t ctr_idx);




Re: [PATCH 3/3] target/riscv: Don't assume PMU counters are continuous

2023-10-12 Thread LIU Zhiwei



On 2023/10/3 20:49, Rob Bradford wrote:

Check the PMU available bitmask when checking if a counter is valid
rather than comparing the index against the number of PMUs.

Signed-off-by: Rob Bradford 
---
  target/riscv/csr.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 85a31dc420..3e126219ba 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -182,7 +182,8 @@ static RISCVException zcmt(CPURISCVState *env, int csrno)
  #if !defined(CONFIG_USER_ONLY)
  static RISCVException mctr(CPURISCVState *env, int csrno)
  {
-int pmu_num = riscv_cpu_cfg(env)->pmu_num;
+RISCVCPU *cpu = RISCV_CPU(env_cpu(env));

Use env_archcpu(env) instead of RISCV_CPU(env_cpu(env)) macro.

+uint32_t pmu_avail_ctrs = cpu->pmu_avail_ctrs;
  int ctr_index;
  int base_csrno = CSR_MHPMCOUNTER3;
  
@@ -191,7 +192,7 @@ static RISCVException mctr(CPURISCVState *env, int csrno)

  base_csrno += 0x80;
  }
  ctr_index = csrno - base_csrno;
-if (!pmu_num || ctr_index >= pmu_num) {
+if ((BIT(ctr_index) & pmu_avail_ctrs >> 3) == 0) {


Otherwise,

Reviewed-by: LIU Zhiwei 

Zhiwei


  /* The PMU is not enabled or counter is out of range */
  return RISCV_EXCP_ILLEGAL_INST;
  }




Re: [PATCH 2/6] target/riscv: Use env_archcpu() in [check_]nanbox()

2023-10-12 Thread LIU Zhiwei



On 2023/10/11 13:31, Philippe Mathieu-Daudé wrote:

On 11/10/23 05:25, LIU Zhiwei wrote:


On 2023/10/11 1:04, Richard Henderson wrote:

On 10/9/23 05:42, LIU Zhiwei wrote:


On 2023/10/9 19:02, Philippe Mathieu-Daudé wrote:

When CPUArchState* is available (here CPURISCVState*), we
can use the fast env_archcpu() macro to get ArchCPU* (here
RISCVCPU*). The QOM cast RISCV_CPU() macro will be slower
when building with --enable-qom-cast-debug.




If so, maybe we have to do this qom cast somewhere.


No, I don't think so.  Or at least not in these places.


Yes.  Perhaps, we should remove all RISCV_CPU macros using after the 
qom objects realized.


Do you think we should remove the RISCV_CPU using in 
riscv_cpu_exec_interrupt? Although it  is not so hot. I think there 
is no reason to use it there.


I have some note in my TODO to check replacing CPUState by ArchCPU in
TCGCPUOps (like the cpu_exec_interrupt handler you mentioned). 


IMHO, this will make it harder for heterogeneous SOC support. ArchCPU is 
not a target agnostic struct.


I must miss something.


However
I'm running out of time, so feel free to try it.

I'd like to have a try if it will not block the heterogeneous SOC support.


Using ArchCPU avoids the cast in target code.

Yes


Except this, there are many other places in hw/ and target/riscv 
using the RISCV_CPU macro.


If a method is exposed as API, we need to check the type. After that
for internal calls this is pointless.


Make sense. Thanks.

Zhiwei



If we know whether we should remove the RISCV_CPU macro use in these 
places, we can do it in another patch.


Thanks,
Zhiwei




r~




Re: [PATCH v2 1/6] target/riscv: Propagate error from PMU setup

2023-10-11 Thread LIU Zhiwei



On 2023/10/11 22:45, Rob Bradford wrote:

More closely follow the QEMU style by returning an Error and propagating
it there is an error relating to the PMU setup.

Further simplify the function by removing the num_counters parameter as
this is available from the passed in cpu pointer.

Signed-off-by: Rob Bradford 
Reviewed-by: Alistair Francis 
---
  target/riscv/cpu.c |  8 +++-
  target/riscv/pmu.c | 19 +--
  target/riscv/pmu.h |  3 ++-
  3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ac2b94b6a6..c9d8fc12fe 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1488,7 +1488,13 @@ static void riscv_cpu_realize_tcg(DeviceState *dev, 
Error **errp)
  }
  
  if (cpu->cfg.pmu_num) {

-if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) {
+riscv_pmu_init(cpu, _err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
+return;
+}
+
+if (cpu->cfg.ext_sscofpmf) {
  cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
riscv_pmu_timer_cb, cpu);
  }
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index 36f6307d28..13801ccb78 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -434,22 +434,21 @@ int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t 
value, uint32_t ctr_idx)
  }
  
  
-int riscv_pmu_init(RISCVCPU *cpu, int num_counters)

+void riscv_pmu_init(RISCVCPU *cpu, Error **errp)
  {
-if (num_counters > (RV_MAX_MHPMCOUNTERS - 3)) {
-return -1;
+uint8_t pmu_num = cpu->cfg.pmu_num;
+
+if (pmu_num > (RV_MAX_MHPMCOUNTERS - 3)) {
+error_setg(errp, "Number of counters exceeds maximum available");
+return;
  }
  
  cpu->pmu_event_ctr_map = g_hash_table_new(g_direct_hash, g_direct_equal);

  if (!cpu->pmu_event_ctr_map) {
-/* PMU support can not be enabled */
-qemu_log_mask(LOG_UNIMP, "PMU events can't be supported\n");
-cpu->cfg.pmu_num = 0;
-return -1;
+error_setg(errp, "Unable to allocate PMU event hash table");
+return;
  }
  
  /* Create a bitmask of available programmable counters */

-cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, num_counters);
-
-return 0;
+cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, pmu_num);
  }
diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
index 2bfb71ba87..88e0713296 100644
--- a/target/riscv/pmu.h
+++ b/target/riscv/pmu.h
@@ -17,13 +17,14 @@
   */
  
  #include "cpu.h"

+#include "qapi/error.h"
  
  bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env,

  uint32_t target_ctr);
  bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env,
uint32_t target_ctr);
  void riscv_pmu_timer_cb(void *priv);
-int riscv_pmu_init(RISCVCPU *cpu, int num_counters);
+void riscv_pmu_init(RISCVCPU *cpu, Error **errp);

Reviewed-by: LIU Zhiwei 

Zhiwei


  int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
 uint32_t ctr_idx);
  int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx);




Re: [PATCH 04/18] target: Declare FOO_CPU_TYPE_NAME/SUFFIX in 'cpu-qom.h'

2023-10-11 Thread LIU Zhiwei



On 2023/10/11 11:21, Philippe Mathieu-Daudé wrote:

Hi Zhiwei,

On 11/10/23 04:51, LIU Zhiwei wrote:


On 2023/10/10 17:28, Philippe Mathieu-Daudé wrote:

Hegerogeneous code needs access to the FOO_CPU_TYPE_NAME()
macro to resolve target CPU types.


Hi Philippe,

I don't understand why should we use FOO_CPU_TYPE_NAME macro to 
resolve target CPU types? In my opinion, we should pass the

CPU typename from command line for heterogeneous case.

Could you make it clearer how should we use FOO_CPU_TYPE_NAME macro 
to resolve target CPU types in heterogeneous case?


To be honest I start to feel a bit lost with the "cpu
resolving type" design.

We are not quite there yet to "create from command line"
or "create from QMP", so I'm prototyping in plain C.
One of my test is:

  #include "target/arm/cpu-qom.h"
  #include "target/hexagon/cpu-qom.h"
  ...

  static void
  my_machine3_init((MachineState *machine)
  {
    CPUState cpu[2];
    ...

    cpu[0] = CPU(object_new(ARM_CPU_TYPE_NAME("cortex-a72")));
    cpu[1] = CPU(object_new(HEXAGON_CPU_TYPE_NAME("v68")));
    ...
  }

The machine code need access to the per-target
FOO_CPU_TYPE_NAME() macros. 


I see what you mean. It works if we will pass the cpu model instead of 
cpu typename to the machine state(Not yet).


Acked-by: LIU Zhiwei 

Zhiwei


I'm not sure what each macro
expands to is considered stable, so IIUC I can't inline and use:

    cpu[0] = CPU(object_new("cortex-a72-arm-cpu"));
    cpu[1] = CPU(object_new("v68"-hexagon-cpu));

That said, maybe I'm mistaken.

Kinda related discussion with Gavin/Igor:
https://lore.kernel.org/qemu-devel/35653f53-a977-02ea-28f6-6fe85b1ef...@redhat.com/ 

(related to 
https://lore.kernel.org/qemu-devel/20230907003553.1636896-1-gs...@redhat.com/).




Thanks,
Zhiwei


Move the declaration
(along with the required FOO_CPU_TYPE_SUFFIX) to "cpu-qom.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/alpha/cpu-qom.h   | 5 -
  target/alpha/cpu.h   | 2 --
  target/avr/cpu-qom.h | 5 -
  target/avr/cpu.h | 2 --
  target/cris/cpu-qom.h    | 5 -
  target/cris/cpu.h    | 2 --
  target/i386/cpu-qom.h    | 3 +++
  target/i386/cpu.h    | 2 --
  target/m68k/cpu-qom.h    | 5 -
  target/m68k/cpu.h    | 2 --
  target/mips/cpu-qom.h    | 3 +++
  target/mips/cpu.h    | 2 --
  target/rx/cpu-qom.h  | 5 -
  target/rx/cpu.h  | 2 --
  target/s390x/cpu-qom.h   | 5 -
  target/s390x/cpu.h   | 2 --
  target/sh4/cpu-qom.h | 5 -
  target/sh4/cpu.h | 2 --
  target/sparc/cpu-qom.h   | 5 -
  target/sparc/cpu.h   | 2 --
  target/tricore/cpu-qom.h | 5 +
  target/tricore/cpu.h | 2 --
  target/xtensa/cpu-qom.h  | 5 -
  target/xtensa/cpu.h  | 2 --
  24 files changed, 47 insertions(+), 33 deletions(-)

diff --git a/target/alpha/cpu-qom.h b/target/alpha/cpu-qom.h
index 1f200724b6..d596d1b69f 100644
--- a/target/alpha/cpu-qom.h
+++ b/target/alpha/cpu-qom.h
@@ -1,5 +1,5 @@
  /*
- * QEMU Alpha CPU
+ * QEMU Alpha CPU QOM header (target agnostic)
   *
   * Copyright (c) 2012 SUSE LINUX Products GmbH
   *
@@ -27,6 +27,9 @@
  OBJECT_DECLARE_CPU_TYPE(AlphaCPU, AlphaCPUClass, ALPHA_CPU)
+#define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU
+#define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX
+
  /**
   * AlphaCPUClass:
   * @parent_realize: The parent class' realize handler.
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index e2a467ec17..ba0d9e3468 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -428,8 +428,6 @@ enum {
  void alpha_translate_init(void);
-#define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU
-#define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX
  #define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU
  void alpha_cpu_list(void);

[...]




Re: [PATCH 2/6] target/riscv: Use env_archcpu() in [check_]nanbox()

2023-10-10 Thread LIU Zhiwei



On 2023/10/11 1:04, Richard Henderson wrote:

On 10/9/23 05:42, LIU Zhiwei wrote:


On 2023/10/9 19:02, Philippe Mathieu-Daudé wrote:

When CPUArchState* is available (here CPURISCVState*), we
can use the fast env_archcpu() macro to get ArchCPU* (here
RISCVCPU*). The QOM cast RISCV_CPU() macro will be slower
when building with --enable-qom-cast-debug.

Inspired-by: Richard W.M. Jones 
Signed-off-by: Philippe Mathieu-Daudé 


Reviewed-by: LIU Zhiwei 

By the way, does the community has the plan to support heterogeneous 
architecture cpus in one soc?


Yes.


Hi Richard,

It's a good news. Thanks.




If so, maybe we have to do this qom cast somewhere.


No, I don't think so.  Or at least not in these places.


Yes.  Perhaps, we should remove all RISCV_CPU macros using after the qom 
objects realized.


Do you think we should remove the RISCV_CPU using in 
riscv_cpu_exec_interrupt? Although it  is not so hot. I think there is 
no reason to use it there.
Except this, there are many other places in hw/ and target/riscv using 
the RISCV_CPU macro.


If we know whether we should remove the RISCV_CPU macro use in these 
places, we can do it in another patch.


Thanks,
Zhiwei




r~




Re: [PATCH 04/18] target: Declare FOO_CPU_TYPE_NAME/SUFFIX in 'cpu-qom.h'

2023-10-10 Thread LIU Zhiwei



On 2023/10/10 17:28, Philippe Mathieu-Daudé wrote:

Hegerogeneous code needs access to the FOO_CPU_TYPE_NAME()
macro to resolve target CPU types.


Hi Philippe,

I don't understand why should we use FOO_CPU_TYPE_NAME macro to resolve 
target CPU types? In my opinion, we should pass the

CPU typename from command line for heterogeneous case.

Could you make it clearer how should we use FOO_CPU_TYPE_NAME macro to 
resolve target CPU types in heterogeneous case?


Thanks,
Zhiwei


Move the declaration
(along with the required FOO_CPU_TYPE_SUFFIX) to "cpu-qom.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/alpha/cpu-qom.h   | 5 -
  target/alpha/cpu.h   | 2 --
  target/avr/cpu-qom.h | 5 -
  target/avr/cpu.h | 2 --
  target/cris/cpu-qom.h| 5 -
  target/cris/cpu.h| 2 --
  target/i386/cpu-qom.h| 3 +++
  target/i386/cpu.h| 2 --
  target/m68k/cpu-qom.h| 5 -
  target/m68k/cpu.h| 2 --
  target/mips/cpu-qom.h| 3 +++
  target/mips/cpu.h| 2 --
  target/rx/cpu-qom.h  | 5 -
  target/rx/cpu.h  | 2 --
  target/s390x/cpu-qom.h   | 5 -
  target/s390x/cpu.h   | 2 --
  target/sh4/cpu-qom.h | 5 -
  target/sh4/cpu.h | 2 --
  target/sparc/cpu-qom.h   | 5 -
  target/sparc/cpu.h   | 2 --
  target/tricore/cpu-qom.h | 5 +
  target/tricore/cpu.h | 2 --
  target/xtensa/cpu-qom.h  | 5 -
  target/xtensa/cpu.h  | 2 --
  24 files changed, 47 insertions(+), 33 deletions(-)

diff --git a/target/alpha/cpu-qom.h b/target/alpha/cpu-qom.h
index 1f200724b6..d596d1b69f 100644
--- a/target/alpha/cpu-qom.h
+++ b/target/alpha/cpu-qom.h
@@ -1,5 +1,5 @@
  /*
- * QEMU Alpha CPU
+ * QEMU Alpha CPU QOM header (target agnostic)
   *
   * Copyright (c) 2012 SUSE LINUX Products GmbH
   *
@@ -27,6 +27,9 @@
  
  OBJECT_DECLARE_CPU_TYPE(AlphaCPU, AlphaCPUClass, ALPHA_CPU)
  
+#define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU

+#define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX
+
  /**
   * AlphaCPUClass:
   * @parent_realize: The parent class' realize handler.
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index e2a467ec17..ba0d9e3468 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -428,8 +428,6 @@ enum {
  
  void alpha_translate_init(void);
  
-#define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU

-#define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX
  #define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU
  
  void alpha_cpu_list(void);

diff --git a/target/avr/cpu-qom.h b/target/avr/cpu-qom.h
index 01ea5f160b..a810d6dc09 100644
--- a/target/avr/cpu-qom.h
+++ b/target/avr/cpu-qom.h
@@ -1,5 +1,5 @@
  /*
- * QEMU AVR CPU
+ * QEMU AVR CPU QOM header (target agnostic)
   *
   * Copyright (c) 2016-2020 Michael Rolnik
   *
@@ -28,6 +28,9 @@
  
  OBJECT_DECLARE_CPU_TYPE(AVRCPU, AVRCPUClass, AVR_CPU)
  
+#define AVR_CPU_TYPE_SUFFIX "-" TYPE_AVR_CPU

+#define AVR_CPU_TYPE_NAME(name) (name AVR_CPU_TYPE_SUFFIX)
+
  /**
   *  AVRCPUClass:
   *  @parent_realize: The parent class' realize handler.
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index 4ce22d8e4f..d3f0cc65d4 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -28,8 +28,6 @@
  #error "AVR 8-bit does not support user mode"
  #endif
  
-#define AVR_CPU_TYPE_SUFFIX "-" TYPE_AVR_CPU

-#define AVR_CPU_TYPE_NAME(name) (name AVR_CPU_TYPE_SUFFIX)
  #define CPU_RESOLVING_TYPE TYPE_AVR_CPU
  
  #define TCG_GUEST_DEFAULT_MO 0

diff --git a/target/cris/cpu-qom.h b/target/cris/cpu-qom.h
index 431a1d536a..02a5b589b8 100644
--- a/target/cris/cpu-qom.h
+++ b/target/cris/cpu-qom.h
@@ -1,5 +1,5 @@
  /*
- * QEMU CRIS CPU
+ * QEMU CRIS CPU QOM header (target agnostic)
   *
   * Copyright (c) 2012 SUSE LINUX Products GmbH
   *
@@ -27,6 +27,9 @@
  
  OBJECT_DECLARE_CPU_TYPE(CRISCPU, CRISCPUClass, CRIS_CPU)
  
+#define CRIS_CPU_TYPE_SUFFIX "-" TYPE_CRIS_CPU

+#define CRIS_CPU_TYPE_NAME(name) (name CRIS_CPU_TYPE_SUFFIX)
+
  /**
   * CRISCPUClass:
   * @parent_realize: The parent class' realize handler.
diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index 676b8e93ca..1af7ae5ef9 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -242,8 +242,6 @@ enum {
  /* CRIS uses 8k pages.  */
  #define MMAP_SHIFT TARGET_PAGE_BITS
  
-#define CRIS_CPU_TYPE_SUFFIX "-" TYPE_CRIS_CPU

-#define CRIS_CPU_TYPE_NAME(name) (name CRIS_CPU_TYPE_SUFFIX)
  #define CPU_RESOLVING_TYPE TYPE_CRIS_CPU
  
  /* MMU modes definitions */

diff --git a/target/i386/cpu-qom.h b/target/i386/cpu-qom.h
index 2350f4ae60..78207c0a7c 100644
--- a/target/i386/cpu-qom.h
+++ b/target/i386/cpu-qom.h
@@ -32,6 +32,9 @@
  
  OBJECT_DECLARE_CPU_TYPE(X86CPU, X86CPUClass, X86_CPU)
  
+#define X86_CPU_TYPE_SUFFIX "-" TYPE_X86_CPU

+#define X86_CPU_TYPE_NAME(name) (name X86_CPU_TYPE_SUFFIX)
+
  typedef struct X86CPUModel X86CPUModel;
  
  /**

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index e1875466b9..862e4f1ff5 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2241,8 +2241,6 @@ 

Re: [PATCH 03/18] target/riscv: Remove CPU_RESOLVING_TYPE from 'cpu-qom.h'

2023-10-10 Thread LIU Zhiwei



On 2023/10/10 17:28, Philippe Mathieu-Daudé wrote:

CPU_RESOLVING_TYPE is a per-target definition, and is
irrelevant for other targets. Move it to "cpu.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/riscv/cpu-qom.h | 1 -
  target/riscv/cpu.h | 2 ++
  2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index 04af50983e..8cb67b84a4 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -27,7 +27,6 @@
  
  #define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU

  #define RISCV_CPU_TYPE_NAME(name) (name RISCV_CPU_TYPE_SUFFIX)
-#define CPU_RESOLVING_TYPE TYPE_RISCV_CPU
  
  #define TYPE_RISCV_CPU_ANY  RISCV_CPU_TYPE_NAME("any")

  #define TYPE_RISCV_CPU_BASE32   RISCV_CPU_TYPE_NAME("rv32")
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index ef9cf21c0c..374b813f20 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -31,6 +31,8 @@
  #include "qapi/qapi-types-common.h"
  #include "cpu-qom.h"
  
+#define CPU_RESOLVING_TYPE TYPE_RISCV_CPU


Reviewed-by: LIU Zhiwei 

Zhiwei


+
  #define TCG_GUEST_DEFAULT_MO 0
  
  /*




Re: [PATCH 10/18] target/riscv: Inline target specific TYPE_RISCV_CPU_BASE definition

2023-10-10 Thread LIU Zhiwei



On 2023/10/10 17:28, Philippe Mathieu-Daudé wrote:

TYPE_RISCV_CPU_BASE depends on the TARGET_RISCV32/TARGET_RISCV64
definitions which are target specific. Such target specific
definition taints "cpu-qom.h".

Since "cpu-qom.h" must be target agnostic, remove its target
specific definition uses by inlining TYPE_RISCV_CPU_BASE in the
two machines using it.

"target/riscv/cpu-qom.h" is now fully target agnostic.

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/riscv/cpu-qom.h | 8 +---
  hw/riscv/spike.c   | 8 +++-
  hw/riscv/virt.c| 8 +++-
  3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index 8cb67b84a4..f607687384 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -1,5 +1,5 @@
  /*
- * QEMU RISC-V CPU QOM header
+ * QEMU RISC-V CPU QOM header (target agnostic)
   *
   * Copyright (c) 2023 Ventana Micro Systems Inc.
   *
@@ -43,12 +43,6 @@
  #define TYPE_RISCV_CPU_VEYRON_V1RISCV_CPU_TYPE_NAME("veyron-v1")
  #define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host")
  
-#if defined(TARGET_RISCV32)

-# define TYPE_RISCV_CPU_BASETYPE_RISCV_CPU_BASE32
-#elif defined(TARGET_RISCV64)
-# define TYPE_RISCV_CPU_BASETYPE_RISCV_CPU_BASE64
-#endif
-
  typedef struct CPUArchState CPURISCVState;
  
  OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU)

diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 81f7e53aed..eae49da6d6 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -349,7 +349,13 @@ static void spike_machine_class_init(ObjectClass *oc, void 
*data)
  mc->init = spike_board_init;
  mc->max_cpus = SPIKE_CPUS_MAX;
  mc->is_default = true;
-mc->default_cpu_type = TYPE_RISCV_CPU_BASE;
+#if defined(TARGET_RISCV32)
+mc->default_cpu_type = TYPE_RISCV_CPU_BASE32;
+#elif defined(TARGET_RISCV64)
+mc->default_cpu_type = TYPE_RISCV_CPU_BASE64;
+#else
+#error unsupported target
+#endif
  mc->possible_cpu_arch_ids = riscv_numa_possible_cpu_arch_ids;
  mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
  mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 5edc1d98d2..620a4e5f07 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1685,7 +1685,13 @@ static void virt_machine_class_init(ObjectClass *oc, 
void *data)
  mc->desc = "RISC-V VirtIO board";
  mc->init = virt_machine_init;
  mc->max_cpus = VIRT_CPUS_MAX;
-mc->default_cpu_type = TYPE_RISCV_CPU_BASE;
+#if defined(TARGET_RISCV32)
+mc->default_cpu_type = TYPE_RISCV_CPU_BASE32;
+#elif defined(TARGET_RISCV64)
+mc->default_cpu_type = TYPE_RISCV_CPU_BASE64;
+#else
+#error unsupported target
+#endif


Reviewed-by: LIU Zhiwei 

Zhiwei


  mc->pci_allow_0_address = true;
  mc->possible_cpu_arch_ids = riscv_numa_possible_cpu_arch_ids;
  mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;




Re: [PATCH] target/riscv: Fix vfwmaccbf16.vf

2023-10-10 Thread LIU Zhiwei



On 2023/10/5 17:57, Max Chou wrote:

The operator (fwmacc16) of vfwmaccbf16.vf helper function should be
replaced by fwmaccbf16.

Signed-off-by: Max Chou 
---
  target/riscv/vector_helper.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 3fb05cc3d6e..c45d94c165c 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3361,7 +3361,7 @@ static uint32_t fwmaccbf16(uint16_t a, uint16_t b, 
uint32_t d, float_status *s)
  
  RVVCALL(OPFVV3, vfwmaccbf16_vv, WOP_UUU_H, H4, H2, H2, fwmaccbf16)

  GEN_VEXT_VV_ENV(vfwmaccbf16_vv, 4)
-RVVCALL(OPFVF3, vfwmaccbf16_vf, WOP_UUU_H, H4, H2, fwmacc16)
+RVVCALL(OPFVF3, vfwmaccbf16_vf, WOP_UUU_H, H4, H2, fwmaccbf16)


Reviewed-by: LIU Zhiwei 

Zhiwei


  GEN_VEXT_VF(vfwmaccbf16_vf, 4)
  
  static uint32_t fwnmacc16(uint16_t a, uint16_t b, uint32_t d, float_status *s)




Re: [PATCH v2] target/riscv: Use a direct cast for better performance

2023-10-09 Thread LIU Zhiwei



On 2023/10/9 20:53, Richard W.M. Jones wrote:

On Mon, Oct 09, 2023 at 08:36:28PM +0800, LIU Zhiwei wrote:

On 2023/10/9 5:50, Richard W.M. Jones wrote:

RISCV_CPU(cs) uses a checked cast.  When QOM cast debugging is enabled
this adds about 5% total overhead when emulating RV64 on x86-64 host.

Using a RISC-V guest with 16 vCPUs, 16 GB of guest RAM, virtio-blk
disk.  The guest has a copy of the qemu source tree.  The test
involves compiling the qemu source tree with 'make clean; time make -j16'.

Before making this change the compile step took 449 & 447 seconds over
two consecutive runs.

After making this change, 428 & 422 seconds.

The saving is about 5%.

Thanks: Paolo Bonzini
Signed-off-by: Richard W.M. Jones 
Reviewed-by: Daniel Henrique Barboza 
---
  target/riscv/cpu_helper.c | 6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 3a02079290..479d9863ae 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -66,7 +66,11 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
uint64_t *cs_base, uint32_t *pflags)
  {
  CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+/*
+ * Using the checked cast RISCV_CPU(cs) imposes ~ 5% overhead when
+ * QOM cast debugging is enabled, so use a direct cast instead.
+ */
+RISCVCPU *cpu = (RISCVCPU *)cs;

This function is very hot. Maybe we should cache the tbflags instead
of calculate it here. Otherwise,

This function is indeed very hot, taking over 20% of total host time
in my guest stress test.

How would we cache the flags?  AIUI they simply depend on machine
state and we must recalculate them either when the machine state
changes (sprinkle "update_tbflags" everywhere)

Yes, we should do in this way.

  or here.  If you have
any suggestions I can try things.

I think it exceeds this patch.



Reviewed-by: LIU Zhiwei 

I posted a v3 based on Philippe's feedback.


OK.

Thanks
Zhiwei



Rich.


Zhiwei


  RISCVExtStatus fs, vs;
  uint32_t flags = 0;




Re: [PATCH 2/6] target/riscv: Use env_archcpu() in [check_]nanbox()

2023-10-09 Thread LIU Zhiwei



On 2023/10/9 19:02, Philippe Mathieu-Daudé wrote:

When CPUArchState* is available (here CPURISCVState*), we
can use the fast env_archcpu() macro to get ArchCPU* (here
RISCVCPU*). The QOM cast RISCV_CPU() macro will be slower
when building with --enable-qom-cast-debug.

Inspired-by: Richard W.M. Jones 
Signed-off-by: Philippe Mathieu-Daudé 


Reviewed-by: LIU Zhiwei 

By the way, does the community has the plan to support heterogeneous 
architecture cpus in one soc?

If so, maybe we have to do this qom cast somewhere.

Zhiwei


---
  target/riscv/internals.h | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index b5f823c7ec..8239ae83cc 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -87,7 +87,7 @@ enum {
  static inline uint64_t nanbox_s(CPURISCVState *env, float32 f)
  {
  /* the value is sign-extended instead of NaN-boxing for zfinx */
-if (RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
+if (env_archcpu(env)->cfg.ext_zfinx) {
  return (int32_t)f;
  } else {
  return f | MAKE_64BIT_MASK(32, 32);
@@ -97,7 +97,7 @@ static inline uint64_t nanbox_s(CPURISCVState *env, float32 f)
  static inline float32 check_nanbox_s(CPURISCVState *env, uint64_t f)
  {
  /* Disable NaN-boxing check when enable zfinx */
-if (RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
+if (env_archcpu(env)->cfg.ext_zfinx) {
  return (uint32_t)f;
  }
  
@@ -113,7 +113,7 @@ static inline float32 check_nanbox_s(CPURISCVState *env, uint64_t f)

  static inline uint64_t nanbox_h(CPURISCVState *env, float16 f)
  {
  /* the value is sign-extended instead of NaN-boxing for zfinx */
-if (RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
+if (env_archcpu(env)->cfg.ext_zfinx) {
  return (int16_t)f;
  } else {
  return f | MAKE_64BIT_MASK(16, 48);
@@ -123,7 +123,7 @@ static inline uint64_t nanbox_h(CPURISCVState *env, float16 
f)
  static inline float16 check_nanbox_h(CPURISCVState *env, uint64_t f)
  {
  /* Disable nanbox check when enable zfinx */
-if (RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
+if (env_archcpu(env)->cfg.ext_zfinx) {
  return (uint16_t)f;
  }
  




Re: [PATCH v2] target/riscv: Use a direct cast for better performance

2023-10-09 Thread LIU Zhiwei



On 2023/10/9 5:50, Richard W.M. Jones wrote:

RISCV_CPU(cs) uses a checked cast.  When QOM cast debugging is enabled
this adds about 5% total overhead when emulating RV64 on x86-64 host.

Using a RISC-V guest with 16 vCPUs, 16 GB of guest RAM, virtio-blk
disk.  The guest has a copy of the qemu source tree.  The test
involves compiling the qemu source tree with 'make clean; time make -j16'.

Before making this change the compile step took 449 & 447 seconds over
two consecutive runs.

After making this change, 428 & 422 seconds.

The saving is about 5%.

Thanks: Paolo Bonzini
Signed-off-by: Richard W.M. Jones 
Reviewed-by: Daniel Henrique Barboza 
---
  target/riscv/cpu_helper.c | 6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 3a02079290..479d9863ae 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -66,7 +66,11 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
uint64_t *cs_base, uint32_t *pflags)
  {
  CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+/*
+ * Using the checked cast RISCV_CPU(cs) imposes ~ 5% overhead when
+ * QOM cast debugging is enabled, so use a direct cast instead.
+ */
+RISCVCPU *cpu = (RISCVCPU *)cs;


This function is very hot. Maybe we should cache the tbflags instead of 
calculate it here. Otherwise,


Reviewed-by: LIU Zhiwei 

Zhiwei


  RISCVExtStatus fs, vs;
  uint32_t flags = 0;
  




Re: [PATCH] MAINTAINERS: Add unowned RISC-V related files to the right sections

2023-09-29 Thread LIU Zhiwei



On 2023/9/29 20:37, Thomas Huth wrote:

There are a bunch of RISC-V files that are currently not covered
by the "get_maintainers.pl" script. Add them to the right sections
in MAINTAINERS to fix this problem.

Signed-off-by: Thomas Huth 


Reviewed-by: LIU Zhiwei 

Zhiwei


---
  MAINTAINERS | 10 +-
  1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 355b1960ce..1313257180 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -317,8 +317,11 @@ R: Daniel Henrique Barboza 
  R: Liu Zhiwei 
  L: qemu-ri...@nongnu.org
  S: Supported
+F: configs/targets/riscv*
+F: docs/system/target-riscv.rst
  F: target/riscv/
  F: hw/riscv/
+F: hw/intc/riscv*
  F: include/hw/riscv/
  F: linux-user/host/riscv32/
  F: linux-user/host/riscv64/
@@ -330,6 +333,7 @@ L: qemu-ri...@nongnu.org
  S: Supported
  F: target/riscv/insn_trans/trans_xthead.c.inc
  F: target/riscv/xthead*.decode
+F: disas/riscv-xthead*
  
  RISC-V XVentanaCondOps extension

  M: Philipp Tomsich 
@@ -337,6 +341,7 @@ L: qemu-ri...@nongnu.org
  S: Maintained
  F: target/riscv/XVentanaCondOps.decode
  F: target/riscv/insn_trans/trans_xventanacondops.c.inc
+F: disas/riscv-xventana*
  
  RENESAS RX CPUs

  R: Yoshinori Sato 
@@ -1518,6 +1523,7 @@ Microchip PolarFire SoC Icicle Kit
  M: Bin Meng 
  L: qemu-ri...@nongnu.org
  S: Supported
+F: docs/system/riscv/microchip-icicle-kit.rst
  F: hw/riscv/microchip_pfsoc.c
  F: hw/char/mchp_pfsoc_mmuart.c
  F: hw/misc/mchp_pfsoc_dmc.c
@@ -1533,6 +1539,7 @@ Shakti C class SoC
  M: Vijai Kumar K 
  L: qemu-ri...@nongnu.org
  S: Supported
+F: docs/system/riscv/shakti-c.rst
  F: hw/riscv/shakti_c.c
  F: hw/char/shakti_uart.c
  F: include/hw/riscv/shakti_c.h
@@ -1544,6 +1551,7 @@ M: Bin Meng 
  M: Palmer Dabbelt 
  L: qemu-ri...@nongnu.org
  S: Supported
+F: docs/system/riscv/sifive_u.rst
  F: hw/*/*sifive*.c
  F: include/hw/*/*sifive*.h
  
@@ -3543,7 +3551,7 @@ M: Alistair Francis 

  L: qemu-ri...@nongnu.org
  S: Maintained
  F: tcg/riscv/
-F: disas/riscv.c
+F: disas/riscv.[ch]
  
  S390 TCG target

  M: Richard Henderson 




Re: [PATCH v2 04/19] target/riscv: move riscv_tcg_ops to tcg-cpu.c

2023-09-19 Thread LIU Zhiwei



On 2023/9/6 17:16, Daniel Henrique Barboza wrote:

Move the remaining of riscv_tcg_ops now that we have a working realize()
implementation.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Andrew Jones 


Reviewed-by: LIU Zhiwei 

Zhiwei


---
  target/riscv/cpu.c | 58 
  target/riscv/cpu.h |  4 ---
  target/riscv/tcg/tcg-cpu.c | 60 +-
  3 files changed, 59 insertions(+), 63 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index e186c026c9..7569955c7e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -838,24 +838,6 @@ static vaddr riscv_cpu_get_pc(CPUState *cs)
  return env->pc;
  }
  
-static void riscv_cpu_synchronize_from_tb(CPUState *cs,

-  const TranslationBlock *tb)
-{
-if (!(tb_cflags(tb) & CF_PCREL)) {
-RISCVCPU *cpu = RISCV_CPU(cs);
-CPURISCVState *env = >env;
-RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
-
-tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
-
-if (xl == MXL_RV32) {
-env->pc = (int32_t) tb->pc;
-} else {
-env->pc = tb->pc;
-}
-}
-}
-
  static bool riscv_cpu_has_work(CPUState *cs)
  {
  #ifndef CONFIG_USER_ONLY
@@ -871,29 +853,6 @@ static bool riscv_cpu_has_work(CPUState *cs)
  #endif
  }
  
-static void riscv_restore_state_to_opc(CPUState *cs,

-   const TranslationBlock *tb,
-   const uint64_t *data)
-{
-RISCVCPU *cpu = RISCV_CPU(cs);
-CPURISCVState *env = >env;
-RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
-target_ulong pc;
-
-if (tb_cflags(tb) & CF_PCREL) {
-pc = (env->pc & TARGET_PAGE_MASK) | data[0];
-} else {
-pc = data[0];
-}
-
-if (xl == MXL_RV32) {
-env->pc = (int32_t)pc;
-} else {
-env->pc = pc;
-}
-env->bins = data[1];
-}
-
  static void riscv_cpu_reset_hold(Object *obj)
  {
  #ifndef CONFIG_USER_ONLY
@@ -1811,23 +1770,6 @@ static const struct SysemuCPUOps riscv_sysemu_ops = {
  };
  #endif
  
-const struct TCGCPUOps riscv_tcg_ops = {

-.initialize = riscv_translate_init,
-.synchronize_from_tb = riscv_cpu_synchronize_from_tb,
-.restore_state_to_opc = riscv_restore_state_to_opc,
-
-#ifndef CONFIG_USER_ONLY
-.tlb_fill = riscv_cpu_tlb_fill,
-.cpu_exec_interrupt = riscv_cpu_exec_interrupt,
-.do_interrupt = riscv_cpu_do_interrupt,
-.do_transaction_failed = riscv_cpu_do_transaction_failed,
-.do_unaligned_access = riscv_cpu_do_unaligned_access,
-.debug_excp_handler = riscv_cpu_debug_excp_handler,
-.debug_check_breakpoint = riscv_cpu_debug_check_breakpoint,
-.debug_check_watchpoint = riscv_cpu_debug_check_watchpoint,
-#endif /* !CONFIG_USER_ONLY */
-};
-
  static bool riscv_cpu_is_dynamic(Object *cpu_obj)
  {
  return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 721bd0b119..2ac00a0304 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -706,10 +706,6 @@ enum riscv_pmu_event_idx {
  RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021,
  };
  
-/* Export tcg_ops until we move everything to tcg/tcg-cpu.c */

-#include "hw/core/tcg-cpu-ops.h"
-extern const struct TCGCPUOps riscv_tcg_ops;
-
  /* used by tcg/tcg-cpu.c*/
  void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t ext_offset, bool en);
  bool cpu_cfg_ext_is_user_set(uint32_t ext_offset);
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index da18851ed4..8698ce4765 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -26,7 +26,66 @@
  #include "qemu/accel.h"
  #include "qemu/error-report.h"
  #include "hw/core/accel-cpu.h"
+#include "hw/core/tcg-cpu-ops.h"
+#include "tcg/tcg.h"
  
+static void riscv_cpu_synchronize_from_tb(CPUState *cs,

+  const TranslationBlock *tb)
+{
+if (!(tb_cflags(tb) & CF_PCREL)) {
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = >env;
+RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
+
+tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+
+if (xl == MXL_RV32) {
+env->pc = (int32_t) tb->pc;
+} else {
+env->pc = tb->pc;
+}
+}
+}
+
+static void riscv_restore_state_to_opc(CPUState *cs,
+   const TranslationBlock *tb,
+   const uint64_t *data)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = >env;
+RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
+target_ulong pc;
+
+if (tb_cflags(tb) & CF_PCREL) {

Re: [PATCH v2 12/19] target/riscv: move KVM only files to kvm subdir

2023-09-19 Thread LIU Zhiwei



On 2023/9/6 17:16, Daniel Henrique Barboza wrote:

Move the files to a 'kvm' dir to promote more code separation between
accelerators and making our lives easier supporting build options such
as --disable-tcg.

Rename kvm.c to kvm-cpu.c to keep it in line with its TCG counterpart.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 


Reviewed-by: LIU Zhiwei 

Zhiwei


---
  hw/intc/riscv_aplic.c | 2 +-
  hw/riscv/virt.c   | 2 +-
  target/riscv/cpu.c| 2 +-
  target/riscv/{kvm.c => kvm/kvm-cpu.c} | 0
  target/riscv/{ => kvm}/kvm_riscv.h| 0
  target/riscv/kvm/meson.build  | 1 +
  target/riscv/meson.build  | 2 +-
  7 files changed, 5 insertions(+), 4 deletions(-)
  rename target/riscv/{kvm.c => kvm/kvm-cpu.c} (100%)
  rename target/riscv/{ => kvm}/kvm_riscv.h (100%)
  create mode 100644 target/riscv/kvm/meson.build

diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
index 99aae8ccbe..c677b5cfbb 100644
--- a/hw/intc/riscv_aplic.c
+++ b/hw/intc/riscv_aplic.c
@@ -32,7 +32,7 @@
  #include "target/riscv/cpu.h"
  #include "sysemu/sysemu.h"
  #include "sysemu/kvm.h"
-#include "kvm_riscv.h"
+#include "kvm/kvm_riscv.h"
  #include "migration/vmstate.h"
  
  #define APLIC_MAX_IDC  (1UL << 14)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 3b259b9305..6d9542f0a2 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -35,7 +35,7 @@
  #include "hw/riscv/virt.h"
  #include "hw/riscv/boot.h"
  #include "hw/riscv/numa.h"
-#include "kvm_riscv.h"
+#include "kvm/kvm_riscv.h"
  #include "hw/intc/riscv_aclint.h"
  #include "hw/intc/riscv_aplic.h"
  #include "hw/intc/riscv_imsic.h"
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c8a19be1af..51567c2f12 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -33,7 +33,7 @@
  #include "fpu/softfloat-helpers.h"
  #include "sysemu/kvm.h"
  #include "sysemu/tcg.h"
-#include "kvm_riscv.h"
+#include "kvm/kvm_riscv.h"
  #include "tcg/tcg.h"
  
  /* RISC-V CPU definitions */

diff --git a/target/riscv/kvm.c b/target/riscv/kvm/kvm-cpu.c
similarity index 100%
rename from target/riscv/kvm.c
rename to target/riscv/kvm/kvm-cpu.c
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm/kvm_riscv.h
similarity index 100%
rename from target/riscv/kvm_riscv.h
rename to target/riscv/kvm/kvm_riscv.h
diff --git a/target/riscv/kvm/meson.build b/target/riscv/kvm/meson.build
new file mode 100644
index 00..7e92415091
--- /dev/null
+++ b/target/riscv/kvm/meson.build
@@ -0,0 +1 @@
+riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm-cpu.c'))
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 3323b78b84..c53962215f 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -24,7 +24,6 @@ riscv_ss.add(files(
'zce_helper.c',
'vcrypto_helper.c'
  ))
-riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
  
  riscv_system_ss = ss.source_set()

  riscv_system_ss.add(files(
@@ -39,6 +38,7 @@ riscv_system_ss.add(files(
  ))
  
  subdir('tcg')

+subdir('kvm')
  
  target_arch += {'riscv': riscv_ss}

  target_softmmu_arch += {'riscv': riscv_system_ss}




Re: [PATCH v2 11/19] target/riscv: introduce KVM AccelCPUClass

2023-09-19 Thread LIU Zhiwei



On 2023/9/6 17:16, Daniel Henrique Barboza wrote:

Add a KVM accelerator class like we did with TCG. The difference is
that, at least for now, we won't be using a realize() implementation for
this accelerator.

We'll start by assiging kvm_riscv_cpu_add_kvm_properties(), renamed to
kvm_cpu_instance_init(), as a 'cpu_instance_init' implementation. Change
riscv_cpu_post_init() to invoke accel_cpu_instance_init(), which will go
through the 'cpu_instance_init' impl of the current acceleration (if
available) and execute it. The end result is that the KVM initial setup,
i.e. starting registers and adding its specific properties, will be done
via this hook.

Add a 'tcg_enabled()' condition in riscv_cpu_post_init() to avoid
calling riscv_cpu_add_user_properties() when running KVM. We'll remove
this condition when the TCG accel class get its own 'cpu_instance_init'
implementation.

Signed-off-by: Daniel Henrique Barboza 


Reviewed-by: LIU Zhiwei 

Zhiwei


---
  target/riscv/cpu.c   |  8 +++-
  target/riscv/kvm.c   | 26 --
  target/riscv/kvm_riscv.h |  6 --
  3 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 50be127f36..c8a19be1af 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1219,7 +1219,9 @@ static bool riscv_cpu_has_user_properties(Object *cpu_obj)
  
  static void riscv_cpu_post_init(Object *obj)

  {
-if (riscv_cpu_has_user_properties(obj)) {
+accel_cpu_instance_init(CPU(obj));
+
+if (tcg_enabled() && riscv_cpu_has_user_properties(obj)) {
  riscv_cpu_add_user_properties(obj);
  }
  
@@ -1589,10 +1591,6 @@ static void riscv_cpu_add_multiext_prop_array(Object *obj,

  static void riscv_cpu_add_user_properties(Object *obj)
  {
  #ifndef CONFIG_USER_ONLY
-if (kvm_enabled()) {
-kvm_riscv_cpu_add_kvm_properties(obj);
-return;
-}
  riscv_add_satp_mode_properties(obj);
  #endif
  
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c

index ef6b2cfffe..492b97d19b 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -31,6 +31,7 @@
  #include "sysemu/kvm_int.h"
  #include "cpu.h"
  #include "trace.h"
+#include "hw/core/accel-cpu.h"
  #include "hw/pci/pci.h"
  #include "exec/memattrs.h"
  #include "exec/address-spaces.h"
@@ -1274,8 +1275,9 @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t 
group_shift,
  kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
  }
  
-void kvm_riscv_cpu_add_kvm_properties(Object *obj)

+static void kvm_cpu_instance_init(CPUState *cs)
  {
+Object *obj = OBJECT(RISCV_CPU(cs));
  DeviceState *dev = DEVICE(obj);
  
  riscv_init_user_properties(obj);

@@ -1287,7 +1289,7 @@ void kvm_riscv_cpu_add_kvm_properties(Object *obj)
  riscv_cpu_add_kvm_unavail_prop_array(obj, riscv_cpu_experimental_exts);
  
  for (Property *prop = riscv_cpu_options; prop && prop->name; prop++) {

-/* Check if KVM created the property already */
+/* Check if we have a specific KVM handler for the option */
  if (object_property_find(obj, prop->name)) {
  continue;
  }
@@ -1295,6 +1297,26 @@ void kvm_riscv_cpu_add_kvm_properties(Object *obj)
  }
  }
  
+static void kvm_cpu_accel_class_init(ObjectClass *oc, void *data)

+{
+AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
+
+acc->cpu_instance_init = kvm_cpu_instance_init;
+}
+
+static const TypeInfo kvm_cpu_accel_type_info = {
+.name = ACCEL_CPU_NAME("kvm"),
+
+.parent = TYPE_ACCEL_CPU,
+.class_init = kvm_cpu_accel_class_init,
+.abstract = true,
+};
+static void kvm_cpu_accel_register_types(void)
+{
+type_register_static(_cpu_accel_type_info);
+}
+type_init(kvm_cpu_accel_register_types);
+
  static void riscv_host_cpu_init(Object *obj)
  {
  CPURISCVState *env = _CPU(obj)->env;
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
index c9ecd9a967..8fe6e3e6fb 100644
--- a/target/riscv/kvm_riscv.h
+++ b/target/riscv/kvm_riscv.h
@@ -20,7 +20,6 @@
  #define QEMU_KVM_RISCV_H
  
  #ifdef CONFIG_KVM

-void kvm_riscv_cpu_add_kvm_properties(Object *obj);
  void kvm_riscv_reset_vcpu(RISCVCPU *cpu);
  void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level);
  void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
@@ -29,11 +28,6 @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t 
group_shift,
uint64_t guest_num);
  void riscv_kvm_aplic_request(void *opaque, int irq, int level);
  #else
-static inline void kvm_riscv_cpu_add_kvm_properties(Object *obj)
-{
-g_assert_not_reached();
-}
-
  static inline void kvm_riscv_reset_vcpu(RISCVCPU *cpu)
  {
  g_assert_not_reached();




Re: [PATCH v2 09/19] target/riscv: make riscv_add_satp_mode_properties() public

2023-09-19 Thread LIU Zhiwei



On 2023/9/6 17:16, Daniel Henrique Barboza wrote:

This function is used for both accelerators. Make it public, and call it
from kvm_riscv_cpu_add_kvm_properties(). This will make it easier to
split KVM specific code for the KVM accelerator class in the next patch.

Signed-off-by: Daniel Henrique Barboza 


Reviewed-by: LIU Zhiwei 

Zhiwei


---
  target/riscv/cpu.c | 5 ++---
  target/riscv/cpu.h | 1 +
  target/riscv/kvm.c | 1 +
  3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0dc9b3201d..50be127f36 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1115,7 +1115,7 @@ static void cpu_riscv_set_satp(Object *obj, Visitor *v, 
const char *name,
  satp_map->init |= 1 << satp;
  }
  
-static void riscv_add_satp_mode_properties(Object *obj)

+void riscv_add_satp_mode_properties(Object *obj)
  {
  RISCVCPU *cpu = RISCV_CPU(obj);
  
@@ -1589,12 +1589,11 @@ static void riscv_cpu_add_multiext_prop_array(Object *obj,

  static void riscv_cpu_add_user_properties(Object *obj)
  {
  #ifndef CONFIG_USER_ONLY
-riscv_add_satp_mode_properties(obj);
-
  if (kvm_enabled()) {
  kvm_riscv_cpu_add_kvm_properties(obj);
  return;
  }
+riscv_add_satp_mode_properties(obj);
  #endif
  
  riscv_cpu_add_misa_properties(obj);

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index b9c4bea3f7..950c2301f2 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -726,6 +726,7 @@ extern const RISCVCPUMultiExtConfig 
riscv_cpu_experimental_exts[];
  extern Property riscv_cpu_options[];
  
  void riscv_cpu_add_misa_properties(Object *cpu_obj);

+void riscv_add_satp_mode_properties(Object *obj);
  
  /* CSR function table */

  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index 7dac01374f..ef6b2cfffe 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -1279,6 +1279,7 @@ void kvm_riscv_cpu_add_kvm_properties(Object *obj)
  DeviceState *dev = DEVICE(obj);
  
  riscv_init_user_properties(obj);

+riscv_add_satp_mode_properties(obj);
  riscv_cpu_add_misa_properties(obj);
  
  riscv_cpu_add_kvm_unavail_prop_array(obj, riscv_cpu_extensions);




Re: [PATCH v2 08/19] target/riscv: move riscv_cpu_add_kvm_properties() to kvm.c

2023-09-19 Thread LIU Zhiwei



On 2023/9/6 17:16, Daniel Henrique Barboza wrote:

We'll introduce the KVM accelerator class with a 'cpu_instance_init'
implementation that is going to be invoked during the common
riscv_cpu_post_init() (via accel_cpu_instance_init()). This
instance_init will execute KVM exclusive code that TCG doesn't care
about, such as adding KVM specific properties, initing registers using a
KVM scratch CPU and so on.

The core of the forementioned cpu_instance_init impl is the current
riscv_cpu_add_kvm_properties() that is being used by the common code via
riscv_cpu_add_user_properties() in cpu.c. Move it to kvm.c, together
will all the relevant artifacts, exporting and renaming it to
kvm_riscv_cpu_add_kvm_properties() so cpu.c can keep using it for now.

To make this work we'll need to export riscv_cpu_extensions,
riscv_cpu_vendor_exts and riscv_cpu_experimental_exts from cpu.c as
well. The TCG accelerator will also need to access those in the near
future so this export will benefit us in the long run.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 


Reviewed-by: LIU Zhiwei 

Zhiwei


---
  target/riscv/cpu.c   | 89 +++-
  target/riscv/cpu.h   | 14 +++
  target/riscv/kvm.c   | 68 +-
  target/riscv/kvm_riscv.h |  2 +-
  4 files changed, 88 insertions(+), 85 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 50c2819d68..0dc9b3201d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1370,7 +1370,7 @@ static RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
   * change MISA bits during realize() (RVG enables MISA
   * bits but the user is warned about it).
   */
-static void riscv_cpu_add_misa_properties(Object *cpu_obj)
+void riscv_cpu_add_misa_properties(Object *cpu_obj)
  {
  int i;
  
@@ -1397,17 +1397,11 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)

  }
  }
  
-typedef struct RISCVCPUMultiExtConfig {

-const char *name;
-uint32_t offset;
-bool enabled;
-} RISCVCPUMultiExtConfig;
-
  #define MULTI_EXT_CFG_BOOL(_name, _prop, _defval) \
  {.name = _name, .offset = CPU_CFG_OFFSET(_prop), \
   .enabled = _defval}
  
-static const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {

+const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
  /* Defaults for standard extensions */
  MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
  MULTI_EXT_CFG_BOOL("Zifencei", ext_ifencei, true),
@@ -1469,7 +1463,7 @@ static const RISCVCPUMultiExtConfig 
riscv_cpu_extensions[] = {
  DEFINE_PROP_END_OF_LIST(),
  };
  
-static const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {

+const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
  MULTI_EXT_CFG_BOOL("xtheadba", ext_xtheadba, false),
  MULTI_EXT_CFG_BOOL("xtheadbb", ext_xtheadbb, false),
  MULTI_EXT_CFG_BOOL("xtheadbs", ext_xtheadbs, false),
@@ -1487,7 +1481,7 @@ static const RISCVCPUMultiExtConfig 
riscv_cpu_vendor_exts[] = {
  };
  
  /* These are experimental so mark with 'x-' */

-static const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
+const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
  /* ePMP 0.9.3 */
  MULTI_EXT_CFG_BOOL("x-epmp", epmp, false),
  MULTI_EXT_CFG_BOOL("x-smaia", ext_smaia, false),
@@ -1513,7 +1507,7 @@ static const RISCVCPUMultiExtConfig 
riscv_cpu_experimental_exts[] = {
  DEFINE_PROP_END_OF_LIST(),
  };
  
-static Property riscv_cpu_options[] = {

+Property riscv_cpu_options[] = {
  DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
  
  DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),

@@ -1574,25 +1568,6 @@ static void cpu_add_multi_ext_prop(Object *cpu_obj,
 multi_cfg->enabled);
  }
  
-#ifndef CONFIG_USER_ONLY

-static void cpu_set_cfg_unavailable(Object *obj, Visitor *v,
-const char *name,
-void *opaque, Error **errp)
-{
-const char *propname = opaque;
-bool value;
-
-if (!visit_type_bool(v, name, , errp)) {
-return;
-}
-
-if (value) {
-error_setg(errp, "extension %s is not available with KVM",
-   propname);
-}
-}
-#endif
-
  static void riscv_cpu_add_multiext_prop_array(Object *obj,
  const RISCVCPUMultiExtConfig *array)
  {
@@ -1605,58 +1580,6 @@ static void riscv_cpu_add_multiext_prop_array(Object 
*obj,
  }
  }
  
-#ifndef CONFIG_USER_ONLY

-static void riscv_cpu_add_kvm_unavail_prop(Object *obj, const char *prop_name)
-{
-/* Check if KVM created the property already */
-if (object_property_find(obj, prop_name)) {
-return;
-}
-
-/*
- * Set the default to disabled for every extension
- * unknown to KVM and error out if the user attempts
- * to enab

Re: [PATCH v2 07/19] target/riscv/cpu.c: mark extensions arrays as 'const'

2023-09-19 Thread LIU Zhiwei



On 2023/9/6 17:16, Daniel Henrique Barboza wrote:

We'll need to export these arrays to the accelerator classes in the next
patches. Mark them as 'const' now because they should not be modified at
runtime.

Note that 'riscv_cpu_options' will also be exported, but can't be marked
as 'const', because the properties are changed via
qdev_property_add_static().

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 


Reviewed-by: LIU Zhiwei 

Zhiwei


---
  target/riscv/cpu.c | 22 +-
  1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c15bb572d4..50c2819d68 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1407,7 +1407,7 @@ typedef struct RISCVCPUMultiExtConfig {
  {.name = _name, .offset = CPU_CFG_OFFSET(_prop), \
   .enabled = _defval}
  
-static RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {

+static const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
  /* Defaults for standard extensions */
  MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
  MULTI_EXT_CFG_BOOL("Zifencei", ext_ifencei, true),
@@ -1469,7 +1469,7 @@ static RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
  DEFINE_PROP_END_OF_LIST(),
  };
  
-static RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {

+static const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
  MULTI_EXT_CFG_BOOL("xtheadba", ext_xtheadba, false),
  MULTI_EXT_CFG_BOOL("xtheadbb", ext_xtheadbb, false),
  MULTI_EXT_CFG_BOOL("xtheadbs", ext_xtheadbs, false),
@@ -1487,7 +1487,7 @@ static RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
  };
  
  /* These are experimental so mark with 'x-' */

-static RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
+static const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
  /* ePMP 0.9.3 */
  MULTI_EXT_CFG_BOOL("x-epmp", epmp, false),
  MULTI_EXT_CFG_BOOL("x-smaia", ext_smaia, false),
@@ -1558,7 +1558,7 @@ static void cpu_get_multi_ext_cfg(Object *obj, Visitor 
*v, const char *name,
  }
  
  static void cpu_add_multi_ext_prop(Object *cpu_obj,

-   RISCVCPUMultiExtConfig *multi_cfg)
+   const RISCVCPUMultiExtConfig *multi_cfg)
  {
  object_property_add(cpu_obj, multi_cfg->name, "bool",
  cpu_get_multi_ext_cfg,
@@ -1594,11 +1594,13 @@ static void cpu_set_cfg_unavailable(Object *obj, 
Visitor *v,
  #endif
  
  static void riscv_cpu_add_multiext_prop_array(Object *obj,

-  RISCVCPUMultiExtConfig *array)
+const RISCVCPUMultiExtConfig *array)
  {
+const RISCVCPUMultiExtConfig *prop;
+
  g_assert(array);
  
-for (RISCVCPUMultiExtConfig *prop = array; prop && prop->name; prop++) {

+for (prop = array; prop && prop->name; prop++) {
  cpu_add_multi_ext_prop(obj, prop);
  }
  }
@@ -1622,11 +1624,13 @@ static void riscv_cpu_add_kvm_unavail_prop(Object *obj, 
const char *prop_name)
  }
  
  static void riscv_cpu_add_kvm_unavail_prop_array(Object *obj,

- RISCVCPUMultiExtConfig *array)
+const RISCVCPUMultiExtConfig *array)
  {
+const RISCVCPUMultiExtConfig *prop;
+
  g_assert(array);
  
-for (RISCVCPUMultiExtConfig *prop = array; prop && prop->name; prop++) {

+for (prop = array; prop && prop->name; prop++) {
  riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
  }
  }
@@ -1689,7 +1693,7 @@ static void riscv_init_max_cpu_extensions(Object *obj)
  {
  RISCVCPU *cpu = RISCV_CPU(obj);
  CPURISCVState *env = >env;
-RISCVCPUMultiExtConfig *prop;
+const RISCVCPUMultiExtConfig *prop;
  
  /* Enable RVG, RVJ and RVV that are disabled by default */

  set_misa(env, env->misa_mxl, env->misa_ext | RVG | RVJ | RVV);




Re: [PATCH v2 06/19] target/riscv: move 'host' CPU declaration to kvm.c

2023-09-19 Thread LIU Zhiwei



On 2023/9/6 17:16, Daniel Henrique Barboza wrote:

This CPU only exists if we're compiling with KVM so move it to the kvm
specific file.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Andrew Jones 
---
  target/riscv/cpu.c | 16 
  target/riscv/kvm.c | 21 +
  2 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 4c6d595067..c15bb572d4 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -652,19 +652,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
  }
  #endif
  
-#if defined(CONFIG_KVM)

-static void riscv_host_cpu_init(Object *obj)
-{
-CPURISCVState *env = _CPU(obj)->env;
-#if defined(TARGET_RISCV32)
-set_misa(env, MXL_RV32, 0);
-#elif defined(TARGET_RISCV64)
-set_misa(env, MXL_RV64, 0);
-#endif
-riscv_cpu_add_user_properties(obj);


Remove this statement in patch 5. Otherwise,

Reviewed-by: LIU Zhiwei 

Zhiwei


-}
-#endif /* CONFIG_KVM */
-
  static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
  {
  ObjectClass *oc;
@@ -2044,9 +2031,6 @@ static const TypeInfo riscv_cpu_type_infos[] = {
  },
  DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY,  riscv_any_cpu_init),
  DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX,  riscv_max_cpu_init),
-#if defined(CONFIG_KVM)
-DEFINE_CPU(TYPE_RISCV_CPU_HOST, riscv_host_cpu_init),
-#endif
  #if defined(TARGET_RISCV32)
  DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE32,   rv32_base_cpu_init),
  DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index 14763ec0cd..b4d8d7a46c 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -1227,3 +1227,24 @@ void kvm_riscv_aia_create(MachineState *machine, 
uint64_t group_shift,
  
  kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();

  }
+
+static void riscv_host_cpu_init(Object *obj)
+{
+CPURISCVState *env = _CPU(obj)->env;
+
+#if defined(TARGET_RISCV32)
+env->misa_mxl_max = env->misa_mxl = MXL_RV32;
+#elif defined(TARGET_RISCV64)
+env->misa_mxl_max = env->misa_mxl = MXL_RV64;
+#endif
+}
+
+static const TypeInfo riscv_kvm_cpu_type_infos[] = {
+{
+.name = TYPE_RISCV_CPU_HOST,
+.parent = TYPE_RISCV_CPU,
+.instance_init = riscv_host_cpu_init,
+}
+};
+
+DEFINE_TYPES(riscv_kvm_cpu_type_infos)




Re: [PATCH v2 03/19] target/riscv: move riscv_cpu_validate_set_extensions() to tcg-cpu.c

2023-09-19 Thread LIU Zhiwei



On 2023/9/6 17:16, Daniel Henrique Barboza wrote:

This function is the core of the RISC-V validations for TCG CPUs, and it
has a lot going on.

Functions in cpu.c were made public to allow them to be used by the KVM
accelerator class later on. 'cpu_cfg_ext_get_min_version()' is notably
hard to move it to another file due to its dependency with isa_edata_arr[]
array, thus make it public and use it as is for now.

riscv_cpu_validate_set_extensions() is kept public because it's used by
csr.c in write_misa().

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 


Reviewed-by: LIU Zhiwei 

Zhiwei


---
  target/riscv/cpu.c | 361 +
  target/riscv/cpu.h |   8 +-
  target/riscv/csr.c |   1 +
  target/riscv/tcg/tcg-cpu.c | 356 
  target/riscv/tcg/tcg-cpu.h |  28 +++
  5 files changed, 397 insertions(+), 357 deletions(-)
  create mode 100644 target/riscv/tcg/tcg-cpu.h

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 59785f5d9a..e186c026c9 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -163,22 +163,21 @@ static const struct isa_ext_data isa_edata_arr[] = {
  /* Hash that stores user set extensions */
  static GHashTable *multi_ext_user_opts;
  
-static bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset)

+bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset)
  {
  bool *ext_enabled = (void *)>cfg + ext_offset;
  
  return *ext_enabled;

  }
  
-static void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t ext_offset,

-   bool en)
+void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t ext_offset, bool en)
  {
  bool *ext_enabled = (void *)>cfg + ext_offset;
  
  *ext_enabled = en;

  }
  
-static int cpu_cfg_ext_get_min_version(uint32_t ext_offset)

+int cpu_cfg_ext_get_min_version(uint32_t ext_offset)
  {
  int i;
  
@@ -193,38 +192,12 @@ static int cpu_cfg_ext_get_min_version(uint32_t ext_offset)

  g_assert_not_reached();
  }
  
-static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)

+bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
  {
  return g_hash_table_contains(multi_ext_user_opts,
   GUINT_TO_POINTER(ext_offset));
  }
  
-static void cpu_cfg_ext_auto_update(RISCVCPU *cpu, uint32_t ext_offset,

-bool value)
-{
-CPURISCVState *env = >env;
-bool prev_val = isa_ext_is_enabled(cpu, ext_offset);
-int min_version;
-
-if (prev_val == value) {
-return;
-}
-
-if (cpu_cfg_ext_is_user_set(ext_offset)) {
-return;
-}
-
-if (value && env->priv_ver != PRIV_VERSION_LATEST) {
-/* Do not enable it if priv_ver is older than min_version */
-min_version = cpu_cfg_ext_get_min_version(ext_offset);
-if (env->priv_ver < min_version) {
-return;
-}
-}
-
-isa_ext_update_enabled(cpu, ext_offset, value);
-}
-
  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",
@@ -1023,46 +996,7 @@ static void riscv_cpu_disas_set_info(CPUState *s, 
disassemble_info *info)
  }
  }
  
-static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,

- Error **errp)
-{
-if (!is_power_of_2(cfg->vlen)) {
-error_setg(errp, "Vector extension VLEN must be power of 2");
-return;
-}
-if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) {
-error_setg(errp,
-   "Vector extension implementation only supports VLEN "
-   "in the range [128, %d]", RV_VLEN_MAX);
-return;
-}
-if (!is_power_of_2(cfg->elen)) {
-error_setg(errp, "Vector extension ELEN must be power of 2");
-return;
-}
-if (cfg->elen > 64 || cfg->elen < 8) {
-error_setg(errp,
-   "Vector extension implementation only supports ELEN "
-   "in the range [8, 64]");
-return;
-}
-if (cfg->vext_spec) {
-if (!g_strcmp0(cfg->vext_spec, "v1.0")) {
-env->vext_ver = VEXT_VERSION_1_00_0;
-} else {
-error_setg(errp, "Unsupported vector spec version '%s'",
-   cfg->vext_spec);
-return;
-}
-} else if (env->vext_ver == 0) {
-qemu_log("vector version is not specified, "
- "use the default value v1.0\n");
-
-env->vext_ver = VEXT_VERSION_1_00_0;
-}
-}
-
-static void riscv_cpu_disabl

Re: [PATCH v2 02/19] target/riscv: move riscv_cpu_realize_tcg() to TCG::cpu_realizefn()

2023-09-19 Thread LIU Zhiwei



On 2023/9/6 17:16, Daniel Henrique Barboza wrote:

riscv_cpu_realize_tcg() was added to allow TCG cpus to have a different
realize() path during the common riscv_cpu_realize(), making it a good
choice to start moving TCG exclusive code to tcg-cpu.c.

Rename it to tcg_cpu_realizefn() and assign it as a implementation of
accel::cpu_realizefn(). tcg_cpu_realizefn() will then be called during
riscv_cpu_realize() via cpu_exec_realizefn(). We'll use a similar
approach with KVM in the near future.

riscv_cpu_validate_set_extensions() is too big and with too many
dependencies to be moved in this same patch. We'll do that next.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 


Reviewed-by: LIU Zhiwei 

Zhiwei


---
  target/riscv/cpu.c | 128 ---
  target/riscv/tcg/tcg-cpu.c | 132 +
  2 files changed, 132 insertions(+), 128 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 2c6972fa0d..59785f5d9a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -23,9 +23,7 @@
  #include "qemu/log.h"
  #include "cpu.h"
  #include "cpu_vendorid.h"
-#include "pmu.h"
  #include "internals.h"
-#include "time_helper.h"
  #include "exec/exec-all.h"
  #include "qapi/error.h"
  #include "qapi/visitor.h"
@@ -1064,29 +1062,6 @@ static void riscv_cpu_validate_v(CPURISCVState *env, 
RISCVCPUConfig *cfg,
  }
  }
  
-static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp)

-{
-CPURISCVState *env = >env;
-int priv_version = -1;
-
-if (cpu->cfg.priv_spec) {
-if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
-priv_version = PRIV_VERSION_1_12_0;
-} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
-priv_version = PRIV_VERSION_1_11_0;
-} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
-priv_version = PRIV_VERSION_1_10_0;
-} else {
-error_setg(errp,
-   "Unsupported privilege spec version '%s'",
-   cpu->cfg.priv_spec);
-return;
-}
-
-env->priv_ver = priv_version;
-}
-}
-
  static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
  {
  CPURISCVState *env = >env;
@@ -,33 +1086,6 @@ static void 
riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
  }
  }
  
-static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)

-{
-RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
-CPUClass *cc = CPU_CLASS(mcc);
-CPURISCVState *env = >env;
-
-/* Validate that MISA_MXL is set properly. */
-switch (env->misa_mxl_max) {
-#ifdef TARGET_RISCV64
-case MXL_RV64:
-case MXL_RV128:
-cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
-break;
-#endif
-case MXL_RV32:
-cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
-break;
-default:
-g_assert_not_reached();
-}
-
-if (env->misa_mxl_max != env->misa_mxl) {
-error_setg(errp, "misa_mxl_max must be equal to misa_mxl");
-return;
-}
-}
-
  /*
   * Check consistency between chosen extensions while setting
   * cpu->cfg accordingly.
@@ -1511,74 +1459,6 @@ static void riscv_cpu_finalize_features(RISCVCPU *cpu, 
Error **errp)
  #endif
  }
  
-static void riscv_cpu_validate_misa_priv(CPURISCVState *env, Error **errp)

-{
-if (riscv_has_ext(env, RVH) && env->priv_ver < PRIV_VERSION_1_12_0) {
-error_setg(errp, "H extension requires priv spec 1.12.0");
-return;
-}
-}
-
-static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp)
-{
-RISCVCPU *cpu = RISCV_CPU(dev);
-CPURISCVState *env = >env;
-Error *local_err = NULL;
-
-if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_HOST)) {
-error_setg(errp, "'host' CPU is not compatible with TCG acceleration");
-return;
-}
-
-riscv_cpu_validate_misa_mxl(cpu, _err);
-if (local_err != NULL) {
-error_propagate(errp, local_err);
-return;
-}
-
-riscv_cpu_validate_priv_spec(cpu, _err);
-if (local_err != NULL) {
-error_propagate(errp, local_err);
-return;
-}
-
-riscv_cpu_validate_misa_priv(env, _err);
-if (local_err != NULL) {
-error_propagate(errp, local_err);
-return;
-}
-
-if (cpu->cfg.epmp && !cpu->cfg.pmp) {
-/*
- * Enhanced PMP should only be available
- * on harts with PMP support
- */
-error_setg(errp, "Invalid configuration: EPMP requires PMP support");
-return;
-}
-
-riscv_cpu_validate_set_extensions(cpu, _err);
-if (local_err != NULL) {
-error_propagate(errp, local_err);
-  

Re: [PATCH v2 01/19] target/riscv: introduce TCG AccelCPUClass

2023-09-19 Thread LIU Zhiwei



On 2023/9/6 17:16, Daniel Henrique Barboza wrote:

target/riscv/cpu.c needs to handle all possible accelerators (TCG and
KVM at this moment) during both init() and realize() time. This forces
us to resort to a lot of "if tcg" and "if kvm" throughout the code,
which isn't wrong, but can get cluttered over time. Splitting
acceleration specific code from cpu.c to its own file will help to
declutter the existing code and it will also make it easier to support
KVM/TCG only builds in the future.

We'll start by adding a new subdir called 'tcg' and a new file called
'tcg-cpu.c'. This file will be used to introduce a new accelerator class
for TCG acceleration in RISC-V, allowing us to center all TCG exclusive
code in its file instead of using 'cpu.c' for everything. This design is
inpired by the work Claudio Fontana did in x86 a few years ago in commit
f5cc5a5c1 ("i386: split cpu accelerators from cpu.c, using
AccelCPUClass").

To avoid moving too much code at once we'll start by adding the new file
and TCG AccelCPUClass declaration. The 'class_init' from the accel class
will init 'tcg_ops', relieving the common riscv_cpu_class_init() from
doing it.

'riscv_tcg_ops' is being exported from 'cpu.c' for now to avoid having
to deal with moving code and files around right now. We'll focus on
decoupling the realize() logic first.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 


Reviewed-by: LIU Zhiwei 

Zhiwei


---
  target/riscv/cpu.c   |  5 +---
  target/riscv/cpu.h   |  4 +++
  target/riscv/meson.build |  2 ++
  target/riscv/tcg/meson.build |  2 ++
  target/riscv/tcg/tcg-cpu.c   | 58 
  5 files changed, 67 insertions(+), 4 deletions(-)
  create mode 100644 target/riscv/tcg/meson.build
  create mode 100644 target/riscv/tcg/tcg-cpu.c

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index be1c028095..2c6972fa0d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -2290,9 +2290,7 @@ static const struct SysemuCPUOps riscv_sysemu_ops = {
  };
  #endif
  
-#include "hw/core/tcg-cpu-ops.h"

-
-static const struct TCGCPUOps riscv_tcg_ops = {
+const struct TCGCPUOps riscv_tcg_ops = {
  .initialize = riscv_translate_init,
  .synchronize_from_tb = riscv_cpu_synchronize_from_tb,
  .restore_state_to_opc = riscv_restore_state_to_opc,
@@ -2451,7 +2449,6 @@ static void riscv_cpu_class_init(ObjectClass *c, void 
*data)
  #endif
  cc->gdb_arch_name = riscv_gdb_arch_name;
  cc->gdb_get_dynamic_xml = riscv_gdb_get_dynamic_xml;
-cc->tcg_ops = _tcg_ops;
  
  object_class_property_add(c, "mvendorid", "uint32", cpu_get_mvendorid,

cpu_set_mvendorid, NULL, NULL);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 577abcd724..b84b62f84e 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -707,6 +707,10 @@ enum riscv_pmu_event_idx {
  RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021,
  };
  
+/* Export tcg_ops until we move everything to tcg/tcg-cpu.c */

+#include "hw/core/tcg-cpu-ops.h"
+extern const struct TCGCPUOps riscv_tcg_ops;
+
  /* CSR function table */
  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
  
diff --git a/target/riscv/meson.build b/target/riscv/meson.build

index 660078bda1..f0486183fa 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -38,5 +38,7 @@ riscv_system_ss.add(files(
'riscv-qmp-cmds.c',
  ))
  
+subdir('tcg')

+
  target_arch += {'riscv': riscv_ss}
  target_softmmu_arch += {'riscv': riscv_system_ss}
diff --git a/target/riscv/tcg/meson.build b/target/riscv/tcg/meson.build
new file mode 100644
index 00..061df3d74a
--- /dev/null
+++ b/target/riscv/tcg/meson.build
@@ -0,0 +1,2 @@
+riscv_ss.add(when: 'CONFIG_TCG', if_true: files(
+  'tcg-cpu.c'))
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
new file mode 100644
index 00..0326cead0d
--- /dev/null
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -0,0 +1,58 @@
+/*
+ * riscv TCG cpu class initialization
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "qemu/accel.h"
+#include "hw/core/accel

Re: [PATCH v2 05/19] target/riscv/cpu.c: add .instance_post_init()

2023-09-19 Thread LIU Zhiwei



On 2023/9/6 17:16, Daniel Henrique Barboza wrote:

All generic CPUs call riscv_cpu_add_user_properties(). The 'max' CPU
calls riscv_init_max_cpu_extensions(). Both can be moved to a common
instance_post_init() callback, implemented in riscv_cpu_post_init(),
called by all CPUs. The call order then becomes:

riscv_cpu_init() -> cpu_init() of each CPU -> .instance_post_init()

In the near future riscv_cpu_post_init() will call the init() function
of the current accelerator, providing a hook for KVM and TCG accel
classes to change the init() process of the CPU.

Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/cpu.c | 42 --
  1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7569955c7e..4c6d595067 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -427,8 +427,6 @@ static void riscv_max_cpu_init(Object *obj)
  mlx = MXL_RV32;
  #endif
  set_misa(env, mlx, 0);
-riscv_cpu_add_user_properties(obj);
-riscv_init_max_cpu_extensions(obj);
  env->priv_ver = PRIV_VERSION_LATEST;
  #ifndef CONFIG_USER_ONLY
  set_satp_mode_max_supported(RISCV_CPU(obj), mlx == MXL_RV32 ?
@@ -442,7 +440,6 @@ static void rv64_base_cpu_init(Object *obj)
  CPURISCVState *env = _CPU(obj)->env;
  /* We set this in the realise function */
  set_misa(env, MXL_RV64, 0);
-riscv_cpu_add_user_properties(obj);
  /* Set latest version of privileged specification */
  env->priv_ver = PRIV_VERSION_LATEST;
  #ifndef CONFIG_USER_ONLY
@@ -566,7 +563,6 @@ static void rv128_base_cpu_init(Object *obj)
  CPURISCVState *env = _CPU(obj)->env;
  /* We set this in the realise function */
  set_misa(env, MXL_RV128, 0);
-riscv_cpu_add_user_properties(obj);
  /* Set latest version of privileged specification */
  env->priv_ver = PRIV_VERSION_LATEST;
  #ifndef CONFIG_USER_ONLY
@@ -579,7 +575,6 @@ static void rv32_base_cpu_init(Object *obj)
  CPURISCVState *env = _CPU(obj)->env;
  /* We set this in the realise function */
  set_misa(env, MXL_RV32, 0);
-riscv_cpu_add_user_properties(obj);
  /* Set latest version of privileged specification */
  env->priv_ver = PRIV_VERSION_LATEST;
  #ifndef CONFIG_USER_ONLY
I think we should also remove riscv_cpu_add_user_properties from host 
cpu init.

@@ -1215,6 +1210,37 @@ static void riscv_cpu_set_irq(void *opaque, int irq, int 
level)
  }
  #endif /* CONFIG_USER_ONLY */
  
+static bool riscv_cpu_is_dynamic(Object *cpu_obj)

+{
+return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
+}
+
+static bool riscv_cpu_has_max_extensions(Object *cpu_obj)
+{
+return object_dynamic_cast(cpu_obj, TYPE_RISCV_CPU_MAX) != NULL;
+}
+
+static bool riscv_cpu_has_user_properties(Object *cpu_obj)
+{
+if (kvm_enabled() &&
+object_dynamic_cast(cpu_obj, TYPE_RISCV_CPU_HOST) != NULL) {
+return true;
+}
+
+return riscv_cpu_is_dynamic(cpu_obj);
+}
+
+static void riscv_cpu_post_init(Object *obj)
+{
+if (riscv_cpu_has_user_properties(obj)) {
+riscv_cpu_add_user_properties(obj);


Otherwise, we will enter here for host cpu.

Thanks,
Zhiwei


+}
+
+if (riscv_cpu_has_max_extensions(obj)) {
+riscv_init_max_cpu_extensions(obj);
+}
+}
+
  static void riscv_cpu_init(Object *obj)
  {
  RISCVCPU *cpu = RISCV_CPU(obj);
@@ -1770,11 +1796,6 @@ static const struct SysemuCPUOps riscv_sysemu_ops = {
  };
  #endif
  
-static bool riscv_cpu_is_dynamic(Object *cpu_obj)

-{
-return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
-}
-
  static void cpu_set_mvendorid(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
  {
@@ -2011,6 +2032,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
  .instance_size = sizeof(RISCVCPU),
  .instance_align = __alignof__(RISCVCPU),
  .instance_init = riscv_cpu_init,
+.instance_post_init = riscv_cpu_post_init,
  .abstract = true,
  .class_size = sizeof(RISCVCPUClass),
  .class_init = riscv_cpu_class_init,




Re: [PATCH] fpu: Add conversions between bfloat16 and [u]int8

2023-09-13 Thread LIU Zhiwei

Hi Richard,

Can you pick it to your tree?

Thanks,
Zhiwei

On 2023/5/31 14:54, LIU Zhiwei wrote:

We missed these functions when upstreaming the bfloat16 support.

Signed-off-by: LIU Zhiwei 
---
  fpu/softfloat.c | 58 +
  include/fpu/softfloat.h | 12 +
  2 files changed, 70 insertions(+)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 108f9cb224..576b026f4e 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -3113,6 +3113,15 @@ int64_t float64_to_int64_scalbn(float64 a, 
FloatRoundMode rmode, int scale,
  return parts_float_to_sint(, rmode, scale, INT64_MIN, INT64_MAX, s);
  }
  
+int8_t bfloat16_to_int8_scalbn(bfloat16 a, FloatRoundMode rmode, int scale,

+   float_status *s)
+{
+FloatParts64 p;
+
+bfloat16_unpack_canonical(, a, s);
+return parts_float_to_sint(, rmode, scale, INT8_MIN, INT8_MAX, s);
+}
+
  int16_t bfloat16_to_int16_scalbn(bfloat16 a, FloatRoundMode rmode, int scale,
   float_status *s)
  {
@@ -3379,6 +3388,11 @@ int64_t floatx80_to_int64_round_to_zero(floatx80 a, 
float_status *s)
  return floatx80_to_int64_scalbn(a, float_round_to_zero, 0, s);
  }
  
+int8_t bfloat16_to_int8(bfloat16 a, float_status *s)

+{
+return bfloat16_to_int8_scalbn(a, s->float_rounding_mode, 0, s);
+}
+
  int16_t bfloat16_to_int16(bfloat16 a, float_status *s)
  {
  return bfloat16_to_int16_scalbn(a, s->float_rounding_mode, 0, s);
@@ -3394,6 +3408,11 @@ int64_t bfloat16_to_int64(bfloat16 a, float_status *s)
  return bfloat16_to_int64_scalbn(a, s->float_rounding_mode, 0, s);
  }
  
+int8_t bfloat16_to_int8_round_to_zero(bfloat16 a, float_status *s)

+{
+return bfloat16_to_int8_scalbn(a, float_round_to_zero, 0, s);
+}
+
  int16_t bfloat16_to_int16_round_to_zero(bfloat16 a, float_status *s)
  {
  return bfloat16_to_int16_scalbn(a, float_round_to_zero, 0, s);
@@ -3503,6 +3522,15 @@ uint64_t float64_to_uint64_scalbn(float64 a, 
FloatRoundMode rmode, int scale,
  return parts_float_to_uint(, rmode, scale, UINT64_MAX, s);
  }
  
+uint8_t bfloat16_to_uint8_scalbn(bfloat16 a, FloatRoundMode rmode,

+ int scale, float_status *s)
+{
+FloatParts64 p;
+
+bfloat16_unpack_canonical(, a, s);
+return parts_float_to_uint(, rmode, scale, UINT8_MAX, s);
+}
+
  uint16_t bfloat16_to_uint16_scalbn(bfloat16 a, FloatRoundMode rmode,
 int scale, float_status *s)
  {
@@ -3728,6 +3756,11 @@ Int128 float128_to_uint128_round_to_zero(float128 a, 
float_status *s)
  return float128_to_uint128_scalbn(a, float_round_to_zero, 0, s);
  }
  
+uint8_t bfloat16_to_uint8(bfloat16 a, float_status *s)

+{
+return bfloat16_to_uint8_scalbn(a, s->float_rounding_mode, 0, s);
+}
+
  uint16_t bfloat16_to_uint16(bfloat16 a, float_status *s)
  {
  return bfloat16_to_uint16_scalbn(a, s->float_rounding_mode, 0, s);
@@ -3743,6 +3776,11 @@ uint64_t bfloat16_to_uint64(bfloat16 a, float_status *s)
  return bfloat16_to_uint64_scalbn(a, s->float_rounding_mode, 0, s);
  }
  
+uint8_t bfloat16_to_uint8_round_to_zero(bfloat16 a, float_status *s)

+{
+return bfloat16_to_uint8_scalbn(a, float_round_to_zero, 0, s);
+}
+
  uint16_t bfloat16_to_uint16_round_to_zero(bfloat16 a, float_status *s)
  {
  return bfloat16_to_uint16_scalbn(a, float_round_to_zero, 0, s);
@@ -3898,6 +3936,11 @@ bfloat16 int16_to_bfloat16_scalbn(int16_t a, int scale, 
float_status *status)
  return int64_to_bfloat16_scalbn(a, scale, status);
  }
  
+bfloat16 int8_to_bfloat16_scalbn(int8_t a, int scale, float_status *status)

+{
+return int64_to_bfloat16_scalbn(a, scale, status);
+}
+
  bfloat16 int64_to_bfloat16(int64_t a, float_status *status)
  {
  return int64_to_bfloat16_scalbn(a, 0, status);
@@ -3913,6 +3956,11 @@ bfloat16 int16_to_bfloat16(int16_t a, float_status 
*status)
  return int64_to_bfloat16_scalbn(a, 0, status);
  }
  
+bfloat16 int8_to_bfloat16(int8_t a, float_status *status)

+{
+return int64_to_bfloat16_scalbn(a, 0, status);
+}
+
  float128 int128_to_float128(Int128 a, float_status *status)
  {
  FloatParts128 p = { };
@@ -4108,6 +4156,11 @@ bfloat16 uint16_to_bfloat16_scalbn(uint16_t a, int 
scale, float_status *status)
  return uint64_to_bfloat16_scalbn(a, scale, status);
  }
  
+bfloat16 uint8_to_bfloat16_scalbn(uint8_t a, int scale, float_status *status)

+{
+return uint64_to_bfloat16_scalbn(a, scale, status);
+}
+
  bfloat16 uint64_to_bfloat16(uint64_t a, float_status *status)
  {
  return uint64_to_bfloat16_scalbn(a, 0, status);
@@ -4123,6 +4176,11 @@ bfloat16 uint16_to_bfloat16(uint16_t a, float_status 
*status)
  return uint64_to_bfloat16_scalbn(a, 0, status);
  }
  
+bfloat16 uint8_to_bfloat16(uint8_t a, float_status *status)

+{
+return uint64_to_bfloat16_scalbn(a, 0, status);
+}
+
  float128 uint64_to_float128(uint64_t a, fl

Re: qemu-riscv32 usermode still broken?

2023-09-12 Thread LIU Zhiwei



On 2023/9/13 6:31, Andreas K. Huettel wrote:

Dear all,

I've once more tried to build up a riscv32 linux install in a qemu-riscv32
usermode systemd-nspawn, and am running into the same problems as some time
ago...

https://dev.gentoo.org/~dilfridge/riscv32/riscv32.tar.xz   (220M)

The problems manifest themselves mostly in bash; if I replace /bin/bash
with a static x86-64 binary (in the tarball as /bin/bash.amd64), bypassing
qemu, I can make the chroot rebuild itself completely.

https://lists.gnu.org/archive/html/bug-bash/2023-09/msg00119.html
^ Here I'm trying to find out more.

Bash tests apparently indicate that argv[0] is overwritten, and that
reading through a pipe or from /dev/tty fails or loses data.

Apart from the bash testsuite failing, symptoms are as follows:

* Something seems wrong in the signal handling (?):


If it is wrong for signal handling and for 32-bit, I guess it may be 
fixed by this patch


https://www.mail-archive.com/qemu-devel@nongnu.org/msg981238.html

And this patch has been merged into master branch yesterday.


May be you can have a try based on the master branch.

Thanks,
Zhiwei


--- our package manager (bash/python combo, there bash) hangs reproducibly at
one point.
--- when I run a console program and try to background it with ctl-z, it hangs
 (only the first time per bash instance, it seems)
 repeated ctl-c gets me back to the shell, then the program is in the
background

riscv32 ~ # python
Python 3.11.5 (main, Aug 31 2023, 21:56:30) [GCC 13.2.1 20230826] on linux
Type "help", "copyright", "credits" or "license" for more information.
[1]+  Stopped python
^C^C^C^C^C^C^C
riscv32 ~ # ^C
riscv32 ~ #
riscv32 ~ # jobs
[1]+  Stopped python
riscv32 ~ # fg
python


--- make, when building something, seems to always start only one job in
parallel

Any advice or debugging would be appreciated.

If we get this running then I can set up regular riscv32 Gentoo stage builds
within a week. [*]

Thanks in advance,
Andreas

PS.
huettel@pinacolada ~ $ /var/lib/machines/riscv32/usr/bin/qemu-riscv32 -version
qemu-riscv32 version 8.1.0
Copyright (c) 2003-2023 Fabrice Bellard and the QEMU Project developers


[*] https://www.gentoo.org/downloads/#riscv





[PATCH v2] qemu/timer: Add host ticks function for RISC-V

2023-09-11 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
---
v2:
 1) Use rdtime instead of rdcycle for dynamic cpuclk adjustment.
 2) Read timeh twice in case of time overflow for 32-bit cpu.
---
 include/qemu/timer.h | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 9a91cb1248..9a366e551f 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -979,6 +979,28 @@ static inline int64_t cpu_get_host_ticks(void)
 return cur - ofs;
 }
 
+#elif defined(__riscv) && __riscv_xlen == 32
+static inline int64_t cpu_get_host_ticks(void)
+{
+uint32_t lo, hi, tmph;
+do {
+asm volatile("RDTIMEH %0\n\t"
+ "RDTIME %1\n\t"
+ "RDTIMEH %2"
+ : "=r"(hi), "=r"(lo), "=r"(tmph));
+} while (unlikely(tmph != hi));
+return lo | (uint64_t)hi << 32;
+}
+
+#elif defined(__riscv) && __riscv_xlen > 32
+static inline int64_t cpu_get_host_ticks(void)
+{
+int64_t val;
+
+asm volatile("RDTIME %0" : "=r"(val));
+return val;
+}
+
 #else
 /* The host CPU doesn't have an easily accessible cycle counter.
Just return a monotonically increasing value.  This will be
-- 
2.17.1




Re: [RESEND] qemu/timer: Add host ticks function for RISC-V

2023-09-10 Thread LIU Zhiwei



On 2023/9/9 22:45, Palmer Dabbelt wrote:

On Sat, 09 Sep 2023 00:18:02 PDT (-0700), pbonz...@redhat.com wrote:

Il sab 9 set 2023, 03:35 Atish Patra  ha scritto:

On Fri, Sep 8, 2023 at 3:29 AM Paolo Bonzini  
wrote:

>
> Queued, thanks.
>

I didn't realize it was already queued. Gmail threads failed me this 
time.

@Paolo Bonzini : Can you please drop this one as this will break as
soon as the host riscv system
has the latest kernel ? I have provided more details in the original
thread.

https://lists.gnu.org/archive/html/qemu-devel/2023-09/msg01941.html



If you have dynamic clock adjustment, does rdcycle increase with a fixed
frequency or does it provide the raw number of clock cycles? If the 
latter,
I agree that it should be provided by perf; but if the frequency is 
fixed

then it would be the same as rdtsc on Intel.


That really depends on exactly how the system is set up, but there are 
systems for which the rdcycle frequency changes when clock speeds 
change and thus will produce surprising answers for users trying to 
use rdcycle as a RTC.  We have rdtime for that, but it has other 
problems (it's trapped and emulated in M-mode on some systems, so it's 
slow and noisy).


So we're steering folks towards perf where we can, as at least that 
way we've got a higher-level interface we can use to describe these 
quirks.


OK. I will send a v2 patch using rdtime.

Thanks,
Zhiwei





Paolo




> Paolo
>
>


--
Regards,
Atish






Re: [PATCH] qemu/timer: Add host ticks function for RISC-V

2023-09-10 Thread LIU Zhiwei



On 2023/9/10 1:43, Richard Henderson wrote:

On 9/7/23 20:23, LIU Zhiwei wrote:

From: LIU Zhiwei 

Signed-off-by: LIU Zhiwei 
---
  include/qemu/timer.h | 19 +++
  1 file changed, 19 insertions(+)

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 9a91cb1248..ce0b66d122 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -979,6 +979,25 @@ static inline int64_t cpu_get_host_ticks(void)
  return cur - ofs;
  }
  +#elif defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 32
+static inline int64_t cpu_get_host_ticks(void)
+{
+    uint32_t lo, hi;
+    asm volatile("RDCYCLE %0\n\t"
+ "RDCYCLEH %1"
+ : "=r"(lo), "=r"(hi));
+    return lo | (uint64_t)hi << 32;
+}
+
+#elif defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen > 32
+static inline int64_t cpu_get_host_ticks(void)
+{
+    int64_t val;
+
+    asm volatile("RDCYCLE %0" : "=r"(cc));
+    return val;
+}


__riscv_xlen should never be undefined.

OK


Don't you need a loop for RDCYCLEH to avoid time going backward?

    do {
    asm("rdcycleh %0\n\t"
    "rdcycle %1\n\t"
    "rdcycleh %2\n\t"
    : "=r"(hi), "=r"(lo), "=r"(tmph));
    } while (unlikely(tmph != hi));


Yes, I think we should do this for XLEN == 32bits.

Thanks,
Zhiwei



r~




[RESEND] qemu/timer: Add host ticks function for RISC-V

2023-09-07 Thread LIU Zhiwei
From: LIU Zhiwei 

Signed-off-by: LIU Zhiwei 
---
 include/qemu/timer.h | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 9a91cb1248..105767c195 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -979,6 +979,25 @@ static inline int64_t cpu_get_host_ticks(void)
 return cur - ofs;
 }
 
+#elif defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 32
+static inline int64_t cpu_get_host_ticks(void)
+{
+uint32_t lo, hi;
+asm volatile("RDCYCLE %0\n\t"
+ "RDCYCLEH %1"
+ : "=r"(lo), "=r"(hi));
+return lo | (uint64_t)hi << 32;
+}
+
+#elif defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen > 32
+static inline int64_t cpu_get_host_ticks(void)
+{
+int64_t val;
+
+asm volatile("RDCYCLE %0" : "=r"(val));
+return val;
+}
+
 #else
 /* The host CPU doesn't have an easily accessible cycle counter.
Just return a monotonically increasing value.  This will be
-- 
2.17.1




[PATCH] qemu/timer: Add host ticks function for RISC-V

2023-09-07 Thread LIU Zhiwei
From: LIU Zhiwei 

Signed-off-by: LIU Zhiwei 
---
 include/qemu/timer.h | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 9a91cb1248..ce0b66d122 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -979,6 +979,25 @@ static inline int64_t cpu_get_host_ticks(void)
 return cur - ofs;
 }
 
+#elif defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 32
+static inline int64_t cpu_get_host_ticks(void)
+{
+uint32_t lo, hi;
+asm volatile("RDCYCLE %0\n\t"
+ "RDCYCLEH %1"
+ : "=r"(lo), "=r"(hi));
+return lo | (uint64_t)hi << 32;
+}
+
+#elif defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen > 32
+static inline int64_t cpu_get_host_ticks(void)
+{
+int64_t val;
+
+asm volatile("RDCYCLE %0" : "=r"(cc));
+return val;
+}
+
 #else
 /* The host CPU doesn't have an easily accessible cycle counter.
Just return a monotonically increasing value.  This will be
-- 
2.17.1




[PATCH 1/1] accel/tcg: Fix the comment for CPUTLBEntryFull

2023-09-01 Thread LIU Zhiwei
When memory region is ram, the lower TARGET_PAGE_BITS is not the
physical section number. Instead, its value is always 0.

Add comment and assert to make it clear.

Signed-off-by: LIU Zhiwei 
---
 accel/tcg/cputlb.c  | 11 +++
 include/exec/cpu-defs.h | 12 ++--
 2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index d68fa6867c..a1ebf75068 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1192,6 +1192,7 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx,
 write_flags = read_flags;
 if (is_ram) {
 iotlb = memory_region_get_ram_addr(section->mr) + xlat;
+assert(!(iotlb & ~TARGET_PAGE_MASK));
 /*
  * Computing is_clean is expensive; avoid all that unless
  * the page is actually writable.
@@ -1254,10 +1255,12 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx,
 
 /* refill the tlb */
 /*
- * At this point iotlb contains a physical section number in the lower
- * TARGET_PAGE_BITS, and either
- *  + the ram_addr_t of the page base of the target RAM (RAM)
- *  + the offset within section->mr of the page base (I/O, ROMD)
+ * When memory region is ram, iotlb contains a TARGET_PAGE_BITS
+ * aligned ram_addr_t of the page base of the target RAM.
+ * Otherwise, iotlb contains
+ *  - a physical section number in the lower TARGET_PAGE_BITS
+ *  - the offset within section->mr of the page base (I/O, ROMD) with the
+ *TARGET_PAGE_BITS masked off.
  * We subtract addr_page (which is page aligned and thus won't
  * disturb the low bits) to give an offset which can be added to the
  * (non-page-aligned) vaddr of the eventual memory access to get
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index fb4c8d480f..350287852e 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -100,12 +100,12 @@
 typedef struct CPUTLBEntryFull {
 /*
  * @xlat_section contains:
- *  - in the lower TARGET_PAGE_BITS, a physical section number
- *  - with the lower TARGET_PAGE_BITS masked off, an offset which
- *must be added to the virtual address to obtain:
- * + the ram_addr_t of the target RAM (if the physical section
- *   number is PHYS_SECTION_NOTDIRTY or PHYS_SECTION_ROM)
- * + the offset within the target MemoryRegion (otherwise)
+ *  - For ram, an offset which must be added to the virtual address
+ *to obtain the ram_addr_t of the target RAM
+ *  - For other memory regions,
+ * + in the lower TARGET_PAGE_BITS, the physical section number
+ * + with the TARGET_PAGE_BITS masked off, the offset within
+ *   the target MemoryRegion
  */
 hwaddr xlat_section;
 
-- 
2.17.1




Re: [RFC PATCH v2 0/6] Add API for list cpu extensions

2023-08-28 Thread LIU Zhiwei



On 2023/8/28 21:58, Igor Mammedov wrote:

On Mon, 28 Aug 2023 16:45:30 +0800
LIU Zhiwei  wrote:


Some times we want to know what is the really mean of one cpu option.
For example, in RISC-V, we usually specify a cpu in this way:
-cpu rv64,v=on

If we don't look into the source code, we can't get the ISA extensions
of this -cpu command line.

In this patch set, we add one list_cpu_props API for common cores. It
will output the enabled ISA extensions.

In the near future, I will also list all possible user configurable
options and all possible extensions for this cpu.

In order to reuse the options parse code, I also add a QemuOptsList
for cpu.

After this patch, we can output the extensions for cpu,
"""
./qemu-system-riscv64 -cpu rv64,help
Enabled extensions:
 
rv64imafdch_zicbom_zicboz_zicsr_zifencei_zihintpause_zawrs_zfa_zba_zbb_zbc_zbs_sstc_svadu

It's not that easy to get features with values in general.
(many factors influence defaults, which may include:
  * properties set and/or added at realize time
  * defaults amended by machine type version
  * defaults amended by -global CLI options
)

To do that consensus was to query features after CPU object is realized.
Typically that implies starting dummy QEMU with needed CPU model and
then using query-cpu-model-expansion command to get actual property values.


I agree query-cpu-model-expansion command is necessary. But for users 
that manually


run qemu command line, it is difficult to for them to give a json-based 
input.


  
The task is solved by implementing query-cpu-model-expansion

command so that user (mainly management layer) could get defaults via QMP.
So if your goal is to get the given cpu defaults to mgmt layer
it is sufficient to implement query-cpu-model-expansion command for riscv.
(CC-ing libvirt folks to see if it picks up the command
automatically for every target or some more work would be needed
on their side as well)

PS:
no one cared about making -cpu name,help working till this moment
and certainly not for linux-user part.

To make this option work reliably it's would be necessary to make sure
that query-cpu-model-expansion work in user mode as well.




Also the timing when 'help' is processed should ensure that
machine is available/initialized (i.e. compat properties are in effect)


Agree. I can defer the helper handler process to the machine initialized 
stage.


Thanks,
Zhiwei



Once you have working query-cpu-model-expansion, your new -cpu foo,help handler
can translate json to human readable format that everyone would agree upon.


To get all configuable options for this cpu, use -device rv64-riscv-cpu,help
"""


v1->v2:

1) Give a hint to use -device cpu,help for configualbe options on cpu
2) Support list_cpu_props for linux user mode
3) Add default to some properties to make -device cpu,help output better


Todo:
1) Fix Daniel comments on KVM and cpu option check
2) Add support for other archs
3) Move qdev help function from qdev-monitor to qdev-property

LIU Zhiwei (6):
   cpu: Add new API cpu_type_by_name
   target/riscv: Add API list_cpu_props
   softmmu/vl: Add qemu_cpu_opts QemuOptsList
   target/riscv: Add default value for misa property
   target/riscv: Add defalut value for string property
   linux-user: Move qemu_cpu_opts to cpu.c

  cpu.c| 63 +---
  hw/core/qdev-prop-internal.h |  2 ++
  hw/core/qdev-properties.c|  7 
  include/exec/cpu-common.h|  3 ++
  include/hw/core/cpu.h| 11 +++
  include/hw/qdev-properties.h |  8 +
  linux-user/main.c| 10 ++
  softmmu/vl.c | 11 +++
  target/riscv/cpu.c   | 30 +
  target/riscv/cpu.h   |  2 ++
  10 files changed, 128 insertions(+), 19 deletions(-)





[RFC PATCH v2 6/6] linux-user: Move qemu_cpu_opts to cpu.c

2023-08-28 Thread LIU Zhiwei
Make qemu_cpu_opts also works for linux user mode. Notice, currently
qdev monitor is not included in linux user mode. We just output
current enabled extentions for RISC-V(without the hint to print all
properties with -device).

With this patch,
"""
qemu-riscv64 -cpu rv64,help
Enabled extensions:

rv64_zicbom_zicboz_zicsr_zifencei_zihintpause_zawrs_zfa_zba_zbb_zbc_zbs_sstc_svadu
"""

Signed-off-by: LIU Zhiwei 
---
 cpu.c | 24 
 include/exec/cpu-common.h |  2 ++
 linux-user/main.c | 10 ++
 softmmu/vl.c  | 24 
 target/riscv/cpu.c|  8 +---
 5 files changed, 41 insertions(+), 27 deletions(-)

diff --git a/cpu.c b/cpu.c
index 712bd02684..590d75def0 100644
--- a/cpu.c
+++ b/cpu.c
@@ -47,6 +47,30 @@
 uintptr_t qemu_host_page_size;
 intptr_t qemu_host_page_mask;
 
+QemuOptsList qemu_cpu_opts = {
+.name = "cpu",
+.implied_opt_name = "cpu_model",
+.head = QTAILQ_HEAD_INITIALIZER(qemu_cpu_opts.head),
+.desc = {
+{ /* end of list */ }
+},
+};
+
+int cpu_help_func(void *opaque, QemuOpts *opts, Error **errp)
+{
+const char *cpu_model, *cpu_type;
+cpu_model = qemu_opt_get(opts, "cpu_model");
+if (!cpu_model) {
+return 1;
+}
+if (!qemu_opt_has_help_opt(opts)) {
+return 0;
+}
+cpu_type = cpu_type_by_name(cpu_model);
+list_cpu_props((CPUState *)object_new(cpu_type));
+return 1;
+}
+
 #ifndef CONFIG_USER_ONLY
 static int cpu_common_post_load(void *opaque, int version_id)
 {
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index b3160d9218..4d385436a5 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -168,4 +168,6 @@ int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
 void list_cpus(void);
 void list_cpu_props(CPUState *);
 
+int cpu_help_func(void *opaque, QemuOpts *opts, Error **errp);
+extern QemuOptsList qemu_cpu_opts;
 #endif /* CPU_COMMON_H */
diff --git a/linux-user/main.c b/linux-user/main.c
index 96be354897..c3ef84b1a7 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -362,6 +362,15 @@ static void handle_arg_cpu(const char *arg)
 list_cpus();
 exit(EXIT_FAILURE);
 }
+QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("cpu"),
+ arg, true);
+if (!opts) {
+exit(1);
+}
+if (qemu_opts_foreach(qemu_find_opts("cpu"),
+  cpu_help_func, NULL, NULL)) {
+exit(0);
+}
 }
 
 static void handle_arg_guest_base(const char *arg)
@@ -720,6 +729,7 @@ int main(int argc, char **argv, char **envp)
 cpu_model = NULL;
 
 qemu_add_opts(_trace_opts);
+qemu_add_opts(_cpu_opts);
 qemu_plugin_add_opts();
 
 optind = parse_args(argc, argv);
diff --git a/softmmu/vl.c b/softmmu/vl.c
index bc30f3954d..d6a395454a 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -218,15 +218,6 @@ static struct {
 { .driver = "virtio-vga-gl",.flag = _vga   },
 };
 
-static QemuOptsList qemu_cpu_opts = {
-.name = "cpu",
-.implied_opt_name = "cpu_model",
-.head = QTAILQ_HEAD_INITIALIZER(qemu_cpu_opts.head),
-.desc = {
-{ /* end of list */ }
-},
-};
-
 static QemuOptsList qemu_rtc_opts = {
 .name = "rtc",
 .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
@@ -1149,21 +1140,6 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, 
Error **errp)
 return 0;
 }
 
-static int cpu_help_func(void *opaque, QemuOpts *opts, Error **errp)
-{
-const char *cpu_model, *cpu_type;
-cpu_model = qemu_opt_get(opts, "cpu_model");
-if (!cpu_model) {
-return 1;
-}
-if (!qemu_opt_has_help_opt(opts)) {
-return 0;
-}
-cpu_type = cpu_type_by_name(cpu_model);
-list_cpu_props((CPUState *)object_new(cpu_type));
-return 1;
-}
-
 static int device_help_func(void *opaque, QemuOpts *opts, Error **errp)
 {
 return qdev_device_help(opts);
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index edcd34e62b..e4318fcc46 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -2229,15 +2229,17 @@ void riscv_cpu_list(void)
 void riscv_cpu_list_props(CPUState *cs)
 {
 char *enabled_isa;
-RISCVCPU *cpu = RISCV_CPU(cs);
-RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
-ObjectClass *oc = OBJECT_CLASS(mcc);
 
 enabled_isa = riscv_isa_string(RISCV_CPU(cs));
 qemu_printf("Enabled extensions:\n");
 qemu_printf("\t%s\n", enabled_isa);
+#ifndef CONFIG_USER_ONLY
+RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
+ObjectClass *oc = OBJECT_CLASS(mcc);
 qemu_printf("To get all configuable options for this cpu, use"
 " -device %s,help\n", object_class_get_name(oc));
+#endif
 }
 
 #define DEFINE_CPU(type_name, initfn)  \
-- 
2.17.1




[RFC PATCH v2 5/6] target/riscv: Add defalut value for string property

2023-08-28 Thread LIU Zhiwei
Before this patch,
"""
qemu-system-riscv64 -device rv64-riscv-cpu,v=true,help

...
vext_spec=
...

"""

After this patch,
"""
vext_spec=    -  (default: "v1.0")
"""

Signed-off-by: LIU Zhiwei 
---
 hw/core/qdev-prop-internal.h | 2 ++
 hw/core/qdev-properties.c| 7 +++
 include/hw/qdev-properties.h | 8 
 target/riscv/cpu.c   | 2 +-
 4 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/hw/core/qdev-prop-internal.h b/hw/core/qdev-prop-internal.h
index d7b77844fe..f0613b9757 100644
--- a/hw/core/qdev-prop-internal.h
+++ b/hw/core/qdev-prop-internal.h
@@ -13,6 +13,8 @@ void qdev_propinfo_get_enum(Object *obj, Visitor *v, const 
char *name,
 void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
 void *opaque, Error **errp);
 
+void qdev_propinfo_set_default_value_string(ObjectProperty *op,
+const Property *prop);
 void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
   const Property *prop);
 void qdev_propinfo_set_default_value_int(ObjectProperty *op,
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 357b8761b5..64f70a7292 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -96,6 +96,12 @@ static ObjectPropertyAccessor *field_prop_setter(const 
PropertyInfo *info)
 return info->set ? field_prop_set : NULL;
 }
 
+void qdev_propinfo_set_default_value_string(ObjectProperty *op,
+const Property *prop)
+{
+object_property_set_default_str(op, prop->defval.p);
+}
+
 void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
 void *opaque, Error **errp)
 {
@@ -488,6 +494,7 @@ const PropertyInfo qdev_prop_string = {
 .release = release_string,
 .get   = get_string,
 .set   = set_string,
+.set_default_value = qdev_propinfo_set_default_value_string,
 };
 
 /* --- on/off/auto --- */
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index e1df08876c..8e5651724a 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -22,6 +22,7 @@ struct Property {
 union {
 int64_t i;
 uint64_t u;
+void *p;
 } defval;
 int  arrayoffset;
 const PropertyInfo *arrayinfo;
@@ -91,6 +92,11 @@ extern const PropertyInfo qdev_prop_link;
 .set_default = true,   \
 .defval.u  = (_type)_defval)
 
+#define DEFINE_PROP_STR(_name, _state, _field, _defval, _prop, _type)  \
+DEFINE_PROP(_name, _state, _field, _prop, _type,   \
+.set_default = true,   \
+.defval.p  = (_type)_defval)
+
 #define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
 DEFINE_PROP(_name, _state, _field, _prop, _type)
 
@@ -171,6 +177,8 @@ extern const PropertyInfo qdev_prop_link;
 DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_size, uint64_t)
 #define DEFINE_PROP_STRING(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
+#define DEFINE_PROP_STRING_DEF(_n, _s, _f, _d) \
+DEFINE_PROP_STR(_n, _s, _f, _d, qdev_prop_string, char*)
 #define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
 DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_on_off_auto, OnOffAuto)
 #define DEFINE_PROP_SIZE32(_n, _s, _f, _d)   \
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 38838cd2c0..edcd34e62b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1769,7 +1769,7 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
 
 DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
-DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
+DEFINE_PROP_STRING_DEF("vext_spec", RISCVCPU, cfg.vext_spec, "v1.0"),
 DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
 DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
 
-- 
2.17.1




[RFC PATCH v2 4/6] target/riscv: Add default value for misa property

2023-08-28 Thread LIU Zhiwei
Before this patch,
"
qemu-system-riscv64 -device rv64-riscv-cpu,v=true,help

...
v=   - Vector operations
...

"

After this patch,
"
v=   - Vector operations (default: false)
"

Signed-off-by: LIU Zhiwei 
---
 target/riscv/cpu.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c2f102fae1..38838cd2c0 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1728,6 +1728,7 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
 int i;
 
 for (i = 0; i < ARRAY_SIZE(misa_ext_cfgs); i++) {
+ObjectProperty *op;
 RISCVCPUMisaExtConfig *misa_cfg = _ext_cfgs[i];
 int bit = misa_cfg->misa_bit;
 
@@ -1739,14 +1740,13 @@ static void riscv_cpu_add_misa_properties(Object 
*cpu_obj)
 continue;
 }
 
-object_property_add(cpu_obj, misa_cfg->name, "bool",
-cpu_get_misa_ext_cfg,
-cpu_set_misa_ext_cfg,
-NULL, (void *)misa_cfg);
+op = object_property_add(cpu_obj, misa_cfg->name, "bool",
+ cpu_get_misa_ext_cfg,
+ cpu_set_misa_ext_cfg,
+ NULL, (void *)misa_cfg);
 object_property_set_description(cpu_obj, misa_cfg->name,
 misa_cfg->description);
-object_property_set_bool(cpu_obj, misa_cfg->name,
- misa_cfg->enabled, NULL);
+object_property_set_default_bool(op, misa_cfg->enabled);
 }
 }
 
-- 
2.17.1




Re: [RFC PATCH 2/3] target/riscv: Add API list_cpu_props

2023-08-28 Thread LIU Zhiwei



On 2023/8/25 21:46, Daniel Henrique Barboza wrote:



On 8/25/23 09:16, LIU Zhiwei wrote:

This API used for output current configuration for one specified CPU.
Currently only RISC-V frontend implements this API.

Signed-off-by: LIU Zhiwei 
---
  cpu.c |  8 
  include/exec/cpu-common.h |  1 +
  target/riscv/cpu.c    | 10 ++
  target/riscv/cpu.h    |  2 ++
  4 files changed, 21 insertions(+)

diff --git a/cpu.c b/cpu.c
index e1a9239d0f..03a313cd72 100644
--- a/cpu.c
+++ b/cpu.c
@@ -299,6 +299,14 @@ void list_cpus(void)
  #endif
  }
  +void list_cpu_props(CPUState *cs)
+{
+    /* XXX: implement xxx_cpu_list_props for targets that still miss 
it */

+#if defined(cpu_list_props)
+    cpu_list_props(cs);
+#endif
+}
+
  #if defined(CONFIG_USER_ONLY)
  void tb_invalidate_phys_addr(hwaddr addr)
  {
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 87dc9a752c..b3160d9218 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -166,5 +166,6 @@ int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
    /* vl.c */
  void list_cpus(void);
+void list_cpu_props(CPUState *);
    #endif /* CPU_COMMON_H */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6b93b04453..3ea18de06f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -2226,6 +2226,16 @@ void riscv_cpu_list(void)
  g_slist_free(list);
  }
  +void riscv_cpu_list_props(CPUState *cs)
+{
+    char *enabled_isa;
+
+    enabled_isa = riscv_isa_string(RISCV_CPU(cs));
+    qemu_printf("Enable extension:\n");


I suggest "Enabled extensions". LGTM otherwise.


Fixed, thanks.

Zhiwei



Daniel


+    qemu_printf("\t%s\n", enabled_isa);
+    /* TODO: output all user configurable options and all possible 
extensions */

+}
+
  #define DEFINE_CPU(type_name, initfn)  \
  {  \
  .name = type_name, \
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6ea22e0eea..af1d47605b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -443,9 +443,11 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr 
address, int size,

  bool probe, uintptr_t retaddr);
  char *riscv_isa_string(RISCVCPU *cpu);
  void riscv_cpu_list(void);
+void riscv_cpu_list_props(CPUState *cs);
  void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
    #define cpu_list riscv_cpu_list
+#define cpu_list_props riscv_cpu_list_props
  #define cpu_mmu_index riscv_cpu_mmu_index
    #ifndef CONFIG_USER_ONLY




[RFC PATCH v2 3/6] softmmu/vl: Add qemu_cpu_opts QemuOptsList

2023-08-28 Thread LIU Zhiwei
This make the cpu works the similar way like the -device option.

For device option,
"""
./qemu-system-riscv64 -device e1000,help
e1000 options:
  acpi-index=-  (default: 0)
  addr=   - Slot and optional function number, example: 06.0 or 
06 (default: -1)
  autonegotiation= - on/off (default: true)
  bootindex=
  extra_mac_registers= - on/off (default: true)
  failover_pair_id=
"""

After this patch, the cpu can output its configurations,
"""
./qemu-system-riscv64 -cpu rv64,help
Enable extension:

rv64imafdch_zicbom_zicboz_zicsr_zifencei_zihintpause_zawrs_zfa_zba_zbb_zbc_zbs_sstc_svadu
"""

Signed-off-by: LIU Zhiwei 
---
 cpu.c |  2 +-
 include/hw/core/cpu.h | 11 +++
 softmmu/vl.c  | 35 +++
 3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/cpu.c b/cpu.c
index 03a313cd72..712bd02684 100644
--- a/cpu.c
+++ b/cpu.c
@@ -257,7 +257,7 @@ void cpu_exec_initfn(CPUState *cpu)
 #endif
 }
 
-static const char *cpu_type_by_name(const char *cpu_model)
+const char *cpu_type_by_name(const char *cpu_model)
 {
 ObjectClass *oc;
 const char *cpu_type;
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index fdcbe87352..49d41afdfa 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -657,6 +657,17 @@ CPUState *cpu_create(const char *typename);
  */
 const char *parse_cpu_option(const char *cpu_option);
 
+/**
+ * cpu_type_by_name:
+ * @cpu_model: The -cpu command line model name.
+ *
+ * Looks up type name by the -cpu command line model name
+ *
+ * Returns: type name of CPU or prints error and terminates process
+ *  if an error occurred.
+ */
+const char *cpu_type_by_name(const char *cpu_model);
+
 /**
  * cpu_has_work:
  * @cpu: The vCPU to check.
diff --git a/softmmu/vl.c b/softmmu/vl.c
index b0b96f67fa..bc30f3954d 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -218,6 +218,15 @@ static struct {
 { .driver = "virtio-vga-gl",.flag = _vga   },
 };
 
+static QemuOptsList qemu_cpu_opts = {
+.name = "cpu",
+.implied_opt_name = "cpu_model",
+.head = QTAILQ_HEAD_INITIALIZER(qemu_cpu_opts.head),
+.desc = {
+{ /* end of list */ }
+},
+};
+
 static QemuOptsList qemu_rtc_opts = {
 .name = "rtc",
 .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
@@ -1140,6 +1149,21 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, 
Error **errp)
 return 0;
 }
 
+static int cpu_help_func(void *opaque, QemuOpts *opts, Error **errp)
+{
+const char *cpu_model, *cpu_type;
+cpu_model = qemu_opt_get(opts, "cpu_model");
+if (!cpu_model) {
+return 1;
+}
+if (!qemu_opt_has_help_opt(opts)) {
+return 0;
+}
+cpu_type = cpu_type_by_name(cpu_model);
+list_cpu_props((CPUState *)object_new(cpu_type));
+return 1;
+}
+
 static int device_help_func(void *opaque, QemuOpts *opts, Error **errp)
 {
 return qdev_device_help(opts);
@@ -2467,6 +2491,11 @@ static void qemu_process_help_options(void)
 exit(0);
 }
 
+if (qemu_opts_foreach(qemu_find_opts("cpu"),
+  cpu_help_func, NULL, NULL)) {
+exit(0);
+}
+
 if (qemu_opts_foreach(qemu_find_opts("device"),
   device_help_func, NULL, NULL)) {
 exit(0);
@@ -2680,6 +2709,7 @@ void qemu_init(int argc, char **argv)
 qemu_add_drive_opts(_runtime_opts);
 qemu_add_opts(_chardev_opts);
 qemu_add_opts(_device_opts);
+qemu_add_opts(_cpu_opts);
 qemu_add_opts(_netdev_opts);
 qemu_add_opts(_nic_opts);
 qemu_add_opts(_net_opts);
@@ -2756,6 +2786,11 @@ void qemu_init(int argc, char **argv)
 case QEMU_OPTION_cpu:
 /* hw initialization will check this */
 cpu_option = optarg;
+opts = qemu_opts_parse_noisily(qemu_find_opts("cpu"),
+   optarg, true);
+if (!opts) {
+exit(1);
+}
 break;
 case QEMU_OPTION_hda:
 case QEMU_OPTION_hdb:
-- 
2.17.1




[RFC PATCH v2 2/6] target/riscv: Add API list_cpu_props

2023-08-28 Thread LIU Zhiwei
This API used for output current configuration for one specified CPU.
Currently only RISC-V frontend implements this API.

Signed-off-by: LIU Zhiwei 
---
 cpu.c |  8 
 include/exec/cpu-common.h |  1 +
 target/riscv/cpu.c| 14 ++
 target/riscv/cpu.h|  2 ++
 4 files changed, 25 insertions(+)

diff --git a/cpu.c b/cpu.c
index e1a9239d0f..03a313cd72 100644
--- a/cpu.c
+++ b/cpu.c
@@ -299,6 +299,14 @@ void list_cpus(void)
 #endif
 }
 
+void list_cpu_props(CPUState *cs)
+{
+/* XXX: implement xxx_cpu_list_props for targets that still miss it */
+#if defined(cpu_list_props)
+cpu_list_props(cs);
+#endif
+}
+
 #if defined(CONFIG_USER_ONLY)
 void tb_invalidate_phys_addr(hwaddr addr)
 {
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 87dc9a752c..b3160d9218 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -166,5 +166,6 @@ int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
 
 /* vl.c */
 void list_cpus(void);
+void list_cpu_props(CPUState *);
 
 #endif /* CPU_COMMON_H */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6b93b04453..c2f102fae1 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -2226,6 +2226,20 @@ void riscv_cpu_list(void)
 g_slist_free(list);
 }
 
+void riscv_cpu_list_props(CPUState *cs)
+{
+char *enabled_isa;
+RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
+ObjectClass *oc = OBJECT_CLASS(mcc);
+
+enabled_isa = riscv_isa_string(RISCV_CPU(cs));
+qemu_printf("Enabled extensions:\n");
+qemu_printf("\t%s\n", enabled_isa);
+qemu_printf("To get all configuable options for this cpu, use"
+" -device %s,help\n", object_class_get_name(oc));
+}
+
 #define DEFINE_CPU(type_name, initfn)  \
 {  \
 .name = type_name, \
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6ea22e0eea..af1d47605b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -443,9 +443,11 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 bool probe, uintptr_t retaddr);
 char *riscv_isa_string(RISCVCPU *cpu);
 void riscv_cpu_list(void);
+void riscv_cpu_list_props(CPUState *cs);
 void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
 
 #define cpu_list riscv_cpu_list
+#define cpu_list_props riscv_cpu_list_props
 #define cpu_mmu_index riscv_cpu_mmu_index
 
 #ifndef CONFIG_USER_ONLY
-- 
2.17.1




[RFC PATCH v2 0/6] Add API for list cpu extensions

2023-08-28 Thread LIU Zhiwei
Some times we want to know what is the really mean of one cpu option.
For example, in RISC-V, we usually specify a cpu in this way:
-cpu rv64,v=on

If we don't look into the source code, we can't get the ISA extensions
of this -cpu command line.

In this patch set, we add one list_cpu_props API for common cores. It
will output the enabled ISA extensions.

In the near future, I will also list all possible user configurable
options and all possible extensions for this cpu.

In order to reuse the options parse code, I also add a QemuOptsList
for cpu.

After this patch, we can output the extensions for cpu,
"""
./qemu-system-riscv64 -cpu rv64,help
Enabled extensions:

rv64imafdch_zicbom_zicboz_zicsr_zifencei_zihintpause_zawrs_zfa_zba_zbb_zbc_zbs_sstc_svadu
To get all configuable options for this cpu, use -device rv64-riscv-cpu,help
"""


v1->v2:

1) Give a hint to use -device cpu,help for configualbe options on cpu
2) Support list_cpu_props for linux user mode
3) Add default to some properties to make -device cpu,help output better


Todo:
1) Fix Daniel comments on KVM and cpu option check
2) Add support for other archs
3) Move qdev help function from qdev-monitor to qdev-property

LIU Zhiwei (6):
  cpu: Add new API cpu_type_by_name
  target/riscv: Add API list_cpu_props
  softmmu/vl: Add qemu_cpu_opts QemuOptsList
  target/riscv: Add default value for misa property
  target/riscv: Add defalut value for string property
  linux-user: Move qemu_cpu_opts to cpu.c

 cpu.c| 63 +---
 hw/core/qdev-prop-internal.h |  2 ++
 hw/core/qdev-properties.c|  7 
 include/exec/cpu-common.h|  3 ++
 include/hw/core/cpu.h| 11 +++
 include/hw/qdev-properties.h |  8 +
 linux-user/main.c| 10 ++
 softmmu/vl.c | 11 +++
 target/riscv/cpu.c   | 30 +
 target/riscv/cpu.h   |  2 ++
 10 files changed, 128 insertions(+), 19 deletions(-)

-- 
2.17.1




[RFC PATCH v2 1/6] cpu: Add new API cpu_type_by_name

2023-08-28 Thread LIU Zhiwei
cpu_type_by_name is used to get the cpu type name from the command
line -cpu.

Currently it is only used by parse_cpu_option. In the next patch, it
will be used by other cpu query functions.

Signed-off-by: LIU Zhiwei 
---
 cpu.c | 31 +++
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/cpu.c b/cpu.c
index 1c948d1161..e1a9239d0f 100644
--- a/cpu.c
+++ b/cpu.c
@@ -257,28 +257,35 @@ void cpu_exec_initfn(CPUState *cpu)
 #endif
 }
 
-const char *parse_cpu_option(const char *cpu_option)
+static const char *cpu_type_by_name(const char *cpu_model)
 {
 ObjectClass *oc;
-CPUClass *cc;
-gchar **model_pieces;
 const char *cpu_type;
 
-model_pieces = g_strsplit(cpu_option, ",", 2);
-if (!model_pieces[0]) {
-error_report("-cpu option cannot be empty");
-exit(1);
-}
 
-oc = cpu_class_by_name(CPU_RESOLVING_TYPE, model_pieces[0]);
+oc = cpu_class_by_name(CPU_RESOLVING_TYPE, cpu_model);
 if (oc == NULL) {
-error_report("unable to find CPU model '%s'", model_pieces[0]);
-g_strfreev(model_pieces);
+error_report("unable to find CPU model '%s'", cpu_model);
 exit(EXIT_FAILURE);
 }
 
 cpu_type = object_class_get_name(oc);
-cc = CPU_CLASS(oc);
+return cpu_type;
+}
+
+const char *parse_cpu_option(const char *cpu_option)
+{
+const char *cpu_type;
+CPUClass *cc;
+gchar **model_pieces;
+
+model_pieces = g_strsplit(cpu_option, ",", 2);
+if (!model_pieces[0]) {
+error_report("-cpu option cannot be empty");
+exit(1);
+}
+cpu_type = cpu_type_by_name(model_pieces[0]);
+cc = CPU_CLASS(object_class_by_name(cpu_type));
 cc->parse_features(cpu_type, model_pieces[1], _fatal);
 g_strfreev(model_pieces);
 return cpu_type;
-- 
2.17.1




Re: [RFC PATCH 3/3] softmmu/vl: Add qemu_cpu_opts QemuOptsList

2023-08-27 Thread LIU Zhiwei

Hi Drew

On 2023/8/25 23:58, Andrew Jones wrote:

On Fri, Aug 25, 2023 at 08:16:51PM +0800, LIU Zhiwei wrote:

This make the cpu works the similar way like the -device option.

For device option,
"""
./qemu-system-riscv64 -device e1000,help
e1000 options:
   acpi-index=-  (default: 0)
   addr=   - Slot and optional function number, example: 06.0 or 
06 (default: -1)
   autonegotiation= - on/off (default: true)
   bootindex=
   extra_mac_registers= - on/off (default: true)
   failover_pair_id=
"""

After this patch, the cpu can output its configurations,
"""
./qemu-system-riscv64 -cpu rv64,help
Enable extension:

rv64imafdch_zicbom_zicboz_zicsr_zifencei_zihintpause_zawrs_zfa_zba_zbb_zbc_zbs_sstc_svadu
"""

I recommend we make it more similar to -device and list the properties
(not just extensions). Besides a listing being easier to read than the
isa string format, listing properties would also output, e.g.

  cbom_blocksize=-  (default: 64)

which would also be helpful.


I agree that we should add more outputs in cpu_list_props to aid the 
understanding of the isa string output. And let users know what they 
should explicitly added the -cpu command line.


I will refer to the -device option output. However, The -device option 
is not enough for cpu model.


"""

qemu-system-riscv64 -device rv64-riscv-cpu,zba=false,help

rv64-riscv-cpu options:
  Zawrs=   -  (default: true)
  Zfa= -  (default: true)
  Zfh= -  (default: false)
  Zfhmin=  -  (default: false)
  Zicsr=   -  (default: true)
  Zifencei=    -  (default: true)
  Zihintpause= -  (default: true)
  Zve32f=  -  (default: false)
  Zve64d=  -  (default: false)
  Zve64f=  -  (default: false)
  a=   - Atomic instructions
  c=   - Compressed instructions
  cbom_blocksize= -  (default: 64)
  cboz_blocksize= -  (default: 64)
  d=   - Double-precision float point

  ...

 unnamed-gpio-in[0]=>
  unnamed-gpio-in[10]=>
  unnamed-gpio-in[11]=>
  unnamed-gpio-in[12]=>
  unnamed-gpio-in[13]=>
  unnamed-gpio-in[14]=>

...

memory=>

...

start-powered-off=

...

  v=   - Vector operations
  vext_spec=

...

  zba= -  (default: true)
  zbb= -  (default: true)
  zbc= -  (default: true)
  zbkb=    -  (default: false)

...

"""

1) IMHO, unnamed-gpio-in and start-powered-off exposing to users is 
meaningless.


2) Option like v and vext_spec doesn't output the defalut value.

3) The zba=false  in command line can't reflect  in the output.

That is the reason  why I want to add a new API cpu_list_props.

Thanks,
Zhwei



Thanks,
drew


Signed-off-by: LIU Zhiwei 
---
  cpu.c |  2 +-
  include/hw/core/cpu.h | 11 +++
  softmmu/vl.c  | 35 +++
  3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/cpu.c b/cpu.c
index 03a313cd72..712bd02684 100644
--- a/cpu.c
+++ b/cpu.c
@@ -257,7 +257,7 @@ void cpu_exec_initfn(CPUState *cpu)
  #endif
  }
  
-static const char *cpu_type_by_name(const char *cpu_model)

+const char *cpu_type_by_name(const char *cpu_model)
  {
  ObjectClass *oc;
  const char *cpu_type;
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index fdcbe87352..49d41afdfa 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -657,6 +657,17 @@ CPUState *cpu_create(const char *typename);
   */
  const char *parse_cpu_option(const char *cpu_option);
  
+/**

+ * cpu_type_by_name:
+ * @cpu_model: The -cpu command line model name.
+ *
+ * Looks up type name by the -cpu command line model name
+ *
+ * Returns: type name of CPU or prints error and terminates process
+ *  if an error occurred.
+ */
+const char *cpu_type_by_name(const char *cpu_model);
+
  /**
   * cpu_has_work:
   * @cpu: The vCPU to check.
diff --git a/softmmu/vl.c b/softmmu/vl.c
index b0b96f67fa..bc30f3954d 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -218,6 +218,15 @@ static struct {
  { .driver = "virtio-vga-gl",.flag = _vga   },
  };
  
+static QemuOptsList qemu_cpu_opts = {

+.name = "cpu",
+.implied_opt_name = "cpu_model",
+.head = QTAILQ_HEAD_INITIALIZER(qemu_cpu_opts.head),
+.desc = {
+{ /* end of list */ }
+},
+};
+
  static QemuOptsList qemu_rtc_opts = {
  .name = "rtc",
  .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
@@ -1140,6 +1149,21 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, 
Error **errp)
  return 0;
  }
  
+static int cpu_help_func(void *opaque, QemuOpts *opts, Error **errp)

+{
+const char *cpu_model, *cpu_type;
+cpu_model = qemu_opt_get(opts, "cpu_model");
+if (!cpu_model) {
+return 1;
+}
+if (!qemu_opt_has_help_opt(opts))

[RFC PATCH 3/3] softmmu/vl: Add qemu_cpu_opts QemuOptsList

2023-08-25 Thread LIU Zhiwei
This make the cpu works the similar way like the -device option.

For device option,
"""
./qemu-system-riscv64 -device e1000,help
e1000 options:
  acpi-index=-  (default: 0)
  addr=   - Slot and optional function number, example: 06.0 or 
06 (default: -1)
  autonegotiation= - on/off (default: true)
  bootindex=
  extra_mac_registers= - on/off (default: true)
  failover_pair_id=
"""

After this patch, the cpu can output its configurations,
"""
./qemu-system-riscv64 -cpu rv64,help
Enable extension:

rv64imafdch_zicbom_zicboz_zicsr_zifencei_zihintpause_zawrs_zfa_zba_zbb_zbc_zbs_sstc_svadu
"""

Signed-off-by: LIU Zhiwei 
---
 cpu.c |  2 +-
 include/hw/core/cpu.h | 11 +++
 softmmu/vl.c  | 35 +++
 3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/cpu.c b/cpu.c
index 03a313cd72..712bd02684 100644
--- a/cpu.c
+++ b/cpu.c
@@ -257,7 +257,7 @@ void cpu_exec_initfn(CPUState *cpu)
 #endif
 }
 
-static const char *cpu_type_by_name(const char *cpu_model)
+const char *cpu_type_by_name(const char *cpu_model)
 {
 ObjectClass *oc;
 const char *cpu_type;
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index fdcbe87352..49d41afdfa 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -657,6 +657,17 @@ CPUState *cpu_create(const char *typename);
  */
 const char *parse_cpu_option(const char *cpu_option);
 
+/**
+ * cpu_type_by_name:
+ * @cpu_model: The -cpu command line model name.
+ *
+ * Looks up type name by the -cpu command line model name
+ *
+ * Returns: type name of CPU or prints error and terminates process
+ *  if an error occurred.
+ */
+const char *cpu_type_by_name(const char *cpu_model);
+
 /**
  * cpu_has_work:
  * @cpu: The vCPU to check.
diff --git a/softmmu/vl.c b/softmmu/vl.c
index b0b96f67fa..bc30f3954d 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -218,6 +218,15 @@ static struct {
 { .driver = "virtio-vga-gl",.flag = _vga   },
 };
 
+static QemuOptsList qemu_cpu_opts = {
+.name = "cpu",
+.implied_opt_name = "cpu_model",
+.head = QTAILQ_HEAD_INITIALIZER(qemu_cpu_opts.head),
+.desc = {
+{ /* end of list */ }
+},
+};
+
 static QemuOptsList qemu_rtc_opts = {
 .name = "rtc",
 .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
@@ -1140,6 +1149,21 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, 
Error **errp)
 return 0;
 }
 
+static int cpu_help_func(void *opaque, QemuOpts *opts, Error **errp)
+{
+const char *cpu_model, *cpu_type;
+cpu_model = qemu_opt_get(opts, "cpu_model");
+if (!cpu_model) {
+return 1;
+}
+if (!qemu_opt_has_help_opt(opts)) {
+return 0;
+}
+cpu_type = cpu_type_by_name(cpu_model);
+list_cpu_props((CPUState *)object_new(cpu_type));
+return 1;
+}
+
 static int device_help_func(void *opaque, QemuOpts *opts, Error **errp)
 {
 return qdev_device_help(opts);
@@ -2467,6 +2491,11 @@ static void qemu_process_help_options(void)
 exit(0);
 }
 
+if (qemu_opts_foreach(qemu_find_opts("cpu"),
+  cpu_help_func, NULL, NULL)) {
+exit(0);
+}
+
 if (qemu_opts_foreach(qemu_find_opts("device"),
   device_help_func, NULL, NULL)) {
 exit(0);
@@ -2680,6 +2709,7 @@ void qemu_init(int argc, char **argv)
 qemu_add_drive_opts(_runtime_opts);
 qemu_add_opts(_chardev_opts);
 qemu_add_opts(_device_opts);
+qemu_add_opts(_cpu_opts);
 qemu_add_opts(_netdev_opts);
 qemu_add_opts(_nic_opts);
 qemu_add_opts(_net_opts);
@@ -2756,6 +2786,11 @@ void qemu_init(int argc, char **argv)
 case QEMU_OPTION_cpu:
 /* hw initialization will check this */
 cpu_option = optarg;
+opts = qemu_opts_parse_noisily(qemu_find_opts("cpu"),
+   optarg, true);
+if (!opts) {
+exit(1);
+}
 break;
 case QEMU_OPTION_hda:
 case QEMU_OPTION_hdb:
-- 
2.17.1




[RFC PATCH 0/3] Add API for list cpu extensions

2023-08-25 Thread LIU Zhiwei
Some times we want to know what is the really mean of one cpu option.
For example, in RISC-V, we usually specify a cpu in this way:
-cpu rv64,v=on

If we don't look into the source code, we can't get the ISA extensions
of this -cpu command line.

In this patch set, we add one list_cpu_props API for common cores. It
will output the enabled ISA extensions.

In the near future, I will also list all possible user configurable
options and all possible extensions for this cpu.

In order to reuse the options parse code, I also add a QemuOptsList
for cpu.


After this patch, we can output the extensions for cpu,
"""
 ./qemu-system-riscv64 -cpu rv64,help
Enable extension:

rv64imafdch_zicbom_zicboz_zicsr_zifencei_zihintpause_zawrs_zfa_zba_zbb_zbc_zbs_sstc_svadu
"""

Notice currently this patch is only working for RISC-V system mode.

Thanks Andrew Jones for your suggestion!

Todo:
1) Output all possible user configurable options and all extensions.
2) Add support for RISC-V linux-user mode
3) Add support for other archs


LIU Zhiwei (3):
  cpu: Add new API cpu_type_by_name
  target/riscv: Add API list_cpu_props
  softmmu/vl: Add qemu_cpu_opts QemuOptsList

 cpu.c | 39 +++
 include/exec/cpu-common.h |  1 +
 include/hw/core/cpu.h | 11 +++
 softmmu/vl.c  | 35 +++
 target/riscv/cpu.c| 10 ++
 target/riscv/cpu.h|  2 ++
 6 files changed, 86 insertions(+), 12 deletions(-)

-- 
2.17.1




[RFC PATCH 2/3] target/riscv: Add API list_cpu_props

2023-08-25 Thread LIU Zhiwei
This API used for output current configuration for one specified CPU.
Currently only RISC-V frontend implements this API.

Signed-off-by: LIU Zhiwei 
---
 cpu.c |  8 
 include/exec/cpu-common.h |  1 +
 target/riscv/cpu.c| 10 ++
 target/riscv/cpu.h|  2 ++
 4 files changed, 21 insertions(+)

diff --git a/cpu.c b/cpu.c
index e1a9239d0f..03a313cd72 100644
--- a/cpu.c
+++ b/cpu.c
@@ -299,6 +299,14 @@ void list_cpus(void)
 #endif
 }
 
+void list_cpu_props(CPUState *cs)
+{
+/* XXX: implement xxx_cpu_list_props for targets that still miss it */
+#if defined(cpu_list_props)
+cpu_list_props(cs);
+#endif
+}
+
 #if defined(CONFIG_USER_ONLY)
 void tb_invalidate_phys_addr(hwaddr addr)
 {
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 87dc9a752c..b3160d9218 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -166,5 +166,6 @@ int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
 
 /* vl.c */
 void list_cpus(void);
+void list_cpu_props(CPUState *);
 
 #endif /* CPU_COMMON_H */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6b93b04453..3ea18de06f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -2226,6 +2226,16 @@ void riscv_cpu_list(void)
 g_slist_free(list);
 }
 
+void riscv_cpu_list_props(CPUState *cs)
+{
+char *enabled_isa;
+
+enabled_isa = riscv_isa_string(RISCV_CPU(cs));
+qemu_printf("Enable extension:\n");
+qemu_printf("\t%s\n", enabled_isa);
+/* TODO: output all user configurable options and all possible extensions 
*/
+}
+
 #define DEFINE_CPU(type_name, initfn)  \
 {  \
 .name = type_name, \
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6ea22e0eea..af1d47605b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -443,9 +443,11 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 bool probe, uintptr_t retaddr);
 char *riscv_isa_string(RISCVCPU *cpu);
 void riscv_cpu_list(void);
+void riscv_cpu_list_props(CPUState *cs);
 void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
 
 #define cpu_list riscv_cpu_list
+#define cpu_list_props riscv_cpu_list_props
 #define cpu_mmu_index riscv_cpu_mmu_index
 
 #ifndef CONFIG_USER_ONLY
-- 
2.17.1




[RFC PATCH 1/3] cpu: Add new API cpu_type_by_name

2023-08-25 Thread LIU Zhiwei
cpu_type_by_name is used to get the cpu type name from the command
line -cpu.

Currently it is only used by parse_cpu_option. In the next patch, it
will be used by other cpu query functions.

Signed-off-by: LIU Zhiwei 
---
 cpu.c | 31 +++
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/cpu.c b/cpu.c
index 1c948d1161..e1a9239d0f 100644
--- a/cpu.c
+++ b/cpu.c
@@ -257,28 +257,35 @@ void cpu_exec_initfn(CPUState *cpu)
 #endif
 }
 
-const char *parse_cpu_option(const char *cpu_option)
+static const char *cpu_type_by_name(const char *cpu_model)
 {
 ObjectClass *oc;
-CPUClass *cc;
-gchar **model_pieces;
 const char *cpu_type;
 
-model_pieces = g_strsplit(cpu_option, ",", 2);
-if (!model_pieces[0]) {
-error_report("-cpu option cannot be empty");
-exit(1);
-}
 
-oc = cpu_class_by_name(CPU_RESOLVING_TYPE, model_pieces[0]);
+oc = cpu_class_by_name(CPU_RESOLVING_TYPE, cpu_model);
 if (oc == NULL) {
-error_report("unable to find CPU model '%s'", model_pieces[0]);
-g_strfreev(model_pieces);
+error_report("unable to find CPU model '%s'", cpu_model);
 exit(EXIT_FAILURE);
 }
 
 cpu_type = object_class_get_name(oc);
-cc = CPU_CLASS(oc);
+return cpu_type;
+}
+
+const char *parse_cpu_option(const char *cpu_option)
+{
+const char *cpu_type;
+CPUClass *cc;
+gchar **model_pieces;
+
+model_pieces = g_strsplit(cpu_option, ",", 2);
+if (!model_pieces[0]) {
+error_report("-cpu option cannot be empty");
+exit(1);
+}
+cpu_type = cpu_type_by_name(model_pieces[0]);
+cc = CPU_CLASS(object_class_by_name(cpu_type));
 cc->parse_features(cpu_type, model_pieces[1], _fatal);
 g_strfreev(model_pieces);
 return cpu_type;
-- 
2.17.1




Re: [PATCH] target/riscv: Allocate itrigger timers only once

2023-08-17 Thread LIU Zhiwei



On 2023/8/17 0:27, Akihiko Odaki wrote:

riscv_trigger_init() had been called on reset events that can happen
several times for a CPU and it allocated timers for itrigger. If old
timers were present, they were simply overwritten by the new timers,
resulting in a memory leak.

Divide riscv_trigger_init() into two functions, namely
riscv_trigger_realize() and riscv_trigger_reset() and call them in
appropriate timing. The timer allocation will happen only once for a
CPU in riscv_trigger_realize().

Fixes: 5a4ae64cac ("target/riscv: Add itrigger support when icount is enabled")
Signed-off-by: Akihiko Odaki 
---
  target/riscv/debug.h |  3 ++-
  target/riscv/cpu.c   |  8 +++-
  target/riscv/debug.c | 15 ---
  3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/target/riscv/debug.h b/target/riscv/debug.h
index c471748d5a..7edc31e7cc 100644
--- a/target/riscv/debug.h
+++ b/target/riscv/debug.h
@@ -143,7 +143,8 @@ void riscv_cpu_debug_excp_handler(CPUState *cs);
  bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
  bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
  
-void riscv_trigger_init(CPURISCVState *env);

+void riscv_trigger_realize(CPURISCVState *env);
+void riscv_trigger_reset(CPURISCVState *env);
  
  bool riscv_itrigger_enabled(CPURISCVState *env);

  void riscv_itrigger_update_priv(CPURISCVState *env);
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index e12b6ef7f6..3bc3f96a58 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -904,7 +904,7 @@ static void riscv_cpu_reset_hold(Object *obj)
  
  #ifndef CONFIG_USER_ONLY

  if (cpu->cfg.debug) {
-riscv_trigger_init(env);
+riscv_trigger_reset(env);
  }
  
  if (kvm_enabled()) {

@@ -1475,6 +1475,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  
  riscv_cpu_register_gdb_regs_for_features(cs);
  
+#ifndef CONFIG_USER_ONLY

+if (cpu->cfg.debug) {
+riscv_trigger_realize(>env);
+}
+#endif
+
  qemu_init_vcpu(cs);
  cpu_reset(cs);
  
diff --git a/target/riscv/debug.c b/target/riscv/debug.c

index 75ee1c4971..1c44403205 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -903,7 +903,17 @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, 
CPUWatchpoint *wp)
  return false;
  }
  
-void riscv_trigger_init(CPURISCVState *env)

+void riscv_trigger_realize(CPURISCVState *env)
+{
+int i;
+
+for (i = 0; i < RV_MAX_TRIGGERS; i++) {
+env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+  riscv_itrigger_timer_cb, env);
+}
+}
+
+void riscv_trigger_reset(CPURISCVState *env)
  {
  target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0);
  int i;
@@ -928,7 +938,6 @@ void riscv_trigger_init(CPURISCVState *env)
  env->tdata3[i] = 0;
  env->cpu_breakpoint[i] = NULL;
  env->cpu_watchpoint[i] = NULL;
-env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
-  riscv_itrigger_timer_cb, env);
+timer_del(env->itrigger_timer[i]);

Reviewed-by: LIU Zhiwei 

Zhiwei


  }
  }




[PATCH v2] linux-user/riscv: Use abi type for target_ucontext

2023-08-10 Thread LIU Zhiwei
We should not use types dependend on host arch for target_ucontext.
This bug is found when run rv32 applications.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Daniel Henrique Barboza 
---
v2:
- Use abi_ptr instead of abi_ulong for uc_link. (Suggest by Philippe 
Mathieu-Daudé)
---
 linux-user/riscv/signal.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
index eaa168199a..f989f7f51f 100644
--- a/linux-user/riscv/signal.c
+++ b/linux-user/riscv/signal.c
@@ -38,8 +38,8 @@ struct target_sigcontext {
 }; /* cf. riscv-linux:arch/riscv/include/uapi/asm/ptrace.h */
 
 struct target_ucontext {
-unsigned long uc_flags;
-struct target_ucontext *uc_link;
+abi_ulong uc_flags;
+abi_ptr uc_link;
 target_stack_t uc_stack;
 target_sigset_t uc_sigmask;
 uint8_t   __unused[1024 / 8 - sizeof(target_sigset_t)];
-- 
2.17.1




Re: [PATCH] linux-user/riscv: Use abi_ulong for target_ucontext

2023-08-10 Thread LIU Zhiwei



On 2023/8/10 18:48, Philippe Mathieu-Daudé wrote:

On 8/8/23 11:34, LIU Zhiwei wrote:

We should not use types dependend on host arch for target_ucontext.
This bug is found when run rv32 applications.

Signed-off-by: LIU Zhiwei 
---
  linux-user/riscv/signal.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
index eaa168199a..ff8634a272 100644
--- a/linux-user/riscv/signal.c
+++ b/linux-user/riscv/signal.c
@@ -38,8 +38,8 @@ struct target_sigcontext {
  }; /* cf. riscv-linux:arch/riscv/include/uapi/asm/ptrace.h */
    struct target_ucontext {
-    unsigned long uc_flags;
-    struct target_ucontext *uc_link;
+    abi_ulong uc_flags;


Correct.


+    abi_ulong uc_link;


Isn't it 'abi_ptr uc_link' instead?


Thanks, I think abi_ptr is better. As RISC-V doesn't has similar ABI as 
sparc32plus(64bit long but 32bit space address). It is also right here. 
And many arches  use the abi_ulong for uc_link, such as ARM.


I will send a v2 patch.

Zhiwei




  target_stack_t uc_stack;
  target_sigset_t uc_sigmask;
  uint8_t   __unused[1024 / 8 - sizeof(target_sigset_t)];







  1   2   3   4   5   6   7   8   9   10   >