Re: [PATCH qemu] timer/i8254: Fix one shot PIT mode

2023-02-26 Thread Michael S. Tsirkin
On Sun, Feb 26, 2023 at 01:58:10AM +, Damien Zammit wrote:
> Currently, the one-shot (mode 1) PIT expires far too quickly,
> due to the output being set under the wrong logic.
> This change fixes the one-shot PIT mode to behave similarly to mode 0.
> 
> TESTED: using the one-shot PIT mode to calibrate a local apic timer.
> 
> Signed-off-by: Damien Zammit 
> 
> ---
>  hw/timer/i8254_common.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c
> index 050875b497..9164576ca9 100644
> --- a/hw/timer/i8254_common.c
> +++ b/hw/timer/i8254_common.c
> @@ -52,10 +52,8 @@ int pit_get_out(PITChannelState *s, int64_t current_time)
>  switch (s->mode) {
>  default:
>  case 0:
> -out = (d >= s->count);
> -break;


I think you need something like
/* FALLTHRU */
here otherwise some gcc versions will warn.

>  case 1:
> -out = (d < s->count);
> +out = (d >= s->count);
>  break;
>  case 2:
>  if ((d % s->count) == 0 && d != 0) {
> --
> 2.39.0
> 




Re: [PATCH qemu] timer/i8254: Fix one shot PIT mode

2023-02-26 Thread Damien Zammit
Hi Michael,

Thanks for reviewing this on a weekend!

On 26/2/23 19:51, Michael S. Tsirkin wrote:
> On Sun, Feb 26, 2023 at 01:58:10AM +, Damien Zammit wrote:
>>   case 0:
>> -out = (d >= s->count);
>> -break;
>
>
> I think you need something like
>   /* FALLTHRU */
> here otherwise some gcc versions will warn.
>
>>   case 1:
>> -out = (d < s->count);
>> +out = (d >= s->count);

It seems that there are quite a number of these consecutive fallthrough cases
without /* FALLTHRU */ in i8254_common.c

Can these be fixed in a separate patch?

Damien




Re: [PATCH qemu] timer/i8254: Fix one shot PIT mode

2023-02-26 Thread Max Filippov
On Sun, Feb 26, 2023 at 1:18 AM Damien Zammit  wrote:
>
> Hi Michael,
>
> Thanks for reviewing this on a weekend!
>
> On 26/2/23 19:51, Michael S. Tsirkin wrote:
> > On Sun, Feb 26, 2023 at 01:58:10AM +, Damien Zammit wrote:
> >>   case 0:
> >> -out = (d >= s->count);
> >> -break;
> >
> >
> > I think you need something like
> >   /* FALLTHRU */
> > here otherwise some gcc versions will warn.
> >
> >>   case 1:
> >> -out = (d < s->count);
> >> +out = (d >= s->count);
>
> It seems that there are quite a number of these consecutive fallthrough cases
> without /* FALLTHRU */ in i8254_common.c
>
> Can these be fixed in a separate patch?

I believe that the comment is only needed when there's code
between the labels and is not needed between the labels that
follow each other.

-- 
Thanks.
-- Max



Re: [PATCH qemu] timer/i8254: Fix one shot PIT mode

2023-02-26 Thread BALATON Zoltan

On Sun, 26 Feb 2023, Max Filippov wrote:

On Sun, Feb 26, 2023 at 1:18 AM Damien Zammit  wrote:


Hi Michael,

Thanks for reviewing this on a weekend!

On 26/2/23 19:51, Michael S. Tsirkin wrote:

On Sun, Feb 26, 2023 at 01:58:10AM +, Damien Zammit wrote:

  case 0:
-out = (d >= s->count);
-break;



I think you need something like
  /* FALLTHRU */
here otherwise some gcc versions will warn.


  case 1:
-out = (d < s->count);
+out = (d >= s->count);


It seems that there are quite a number of these consecutive fallthrough cases
without /* FALLTHRU */ in i8254_common.c

Can these be fixed in a separate patch?


I believe that the comment is only needed when there's code
between the labels and is not needed between the labels that
follow each other.


I think so too, I have some of these consecutive case labels in my code 
and never had a problem with that. Only when you have a statement between 
labels without break is when a comment is needed.


Regards,
BALATON Zoltan

Re: [PATCH v6 0/5] dump: Make most of it target agnostic (build once)

2023-02-26 Thread Marc-André Lureau
On Sat, Feb 25, 2023 at 1:49 PM Philippe Mathieu-Daudé 
wrote:

> All series reviewed.
>
> Since v5:
> - reword one commit description (Thomas)
> - drop CONFIG_SOFTMMU, unify softmmu_ss (Richard)
>
> Since v4:
> - more unused headers removed
> - KISS, use a bit of #ifdef'ry to avoid a stub file
>
> Thanks to Richard help, we can now build dump.o once
> for all targets, keeping win_dump.o for x86* targets.
>
> Philippe Mathieu-Daudé (5):
>   dump: Replace tswapN() -> cpu_to_dumpN()
>   dump: Replace TARGET_PAGE_SIZE -> qemu_target_page_size()
>   dump: Clean included headers
>   dump: Simplify compiling win_dump.o by introducing
> win_dump_available()
>   dump: Add create_win_dump() stub for non-x86 targets
>
>  dump/dump-hmp-cmds.c |  2 +-
>  dump/dump.c  | 35 +--
>  dump/meson.build |  6 ++
>  dump/win_dump.c  | 38 --
>  dump/win_dump.h  |  5 -
>  5 files changed, 48 insertions(+), 38 deletions(-)
>
>
Reviewed-by: Marc-André Lureau 


Re: [PATCH 51/76] target/riscv: Drop ftemp_new

2023-02-26 Thread liweiwei



On 2023/2/25 17:14, Richard Henderson wrote:

Translators are no longer required to free tcg temporaries,
therefore there's no need to record temps for later freeing.
Replace the few uses with tcg_temp_new_i64.

Signed-off-by: Richard Henderson 


How about the temp_new?

Regards,

Weiwei Li


---
  target/riscv/translate.c | 24 
  1 file changed, 4 insertions(+), 20 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index f9d5d1097e..273e566d66 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -106,9 +106,6 @@ typedef struct DisasContext {
  TCGv zero;
  /* Space for 3 operands plus 1 extra for address computation. */
  TCGv temp[4];
-/* Space for 4 operands(1 dest and <=3 src) for float point computation */
-TCGv_i64 ftemp[4];
-uint8_t nftemp;
  /* PointerMasking extension */
  bool pm_mask_enabled;
  bool pm_base_enabled;
@@ -431,12 +428,6 @@ static void gen_set_gpr128(DisasContext *ctx, int reg_num, 
TCGv rl, TCGv rh)
  }
  }
  
-static TCGv_i64 ftemp_new(DisasContext *ctx)

-{
-assert(ctx->nftemp < ARRAY_SIZE(ctx->ftemp));
-return ctx->ftemp[ctx->nftemp++] = tcg_temp_new_i64();
-}
-
  static TCGv_i64 get_fpr_hs(DisasContext *ctx, int reg_num)
  {
  if (!ctx->cfg_ptr->ext_zfinx) {
@@ -450,7 +441,7 @@ static TCGv_i64 get_fpr_hs(DisasContext *ctx, int reg_num)
  case MXL_RV32:
  #ifdef TARGET_RISCV32
  {
-TCGv_i64 t = ftemp_new(ctx);
+TCGv_i64 t = tcg_temp_new_i64();
  tcg_gen_ext_i32_i64(t, cpu_gpr[reg_num]);
  return t;
  }
@@ -476,7 +467,7 @@ static TCGv_i64 get_fpr_d(DisasContext *ctx, int reg_num)
  switch (get_xl(ctx)) {
  case MXL_RV32:
  {
-TCGv_i64 t = ftemp_new(ctx);
+TCGv_i64 t = tcg_temp_new_i64();
  tcg_gen_concat_tl_i64(t, cpu_gpr[reg_num], cpu_gpr[reg_num + 1]);
  return t;
  }
@@ -496,12 +487,12 @@ static TCGv_i64 dest_fpr(DisasContext *ctx, int reg_num)
  }
  
  if (reg_num == 0) {

-return ftemp_new(ctx);
+return tcg_temp_new_i64();
  }
  
  switch (get_xl(ctx)) {

  case MXL_RV32:
-return ftemp_new(ctx);
+return tcg_temp_new_i64();
  #ifdef TARGET_RISCV64
  case MXL_RV64:
  return cpu_gpr[reg_num];
@@ -1207,8 +1198,6 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
  ctx->cs = cs;
  ctx->ntemp = 0;
  memset(ctx->temp, 0, sizeof(ctx->temp));
-ctx->nftemp = 0;
-memset(ctx->ftemp, 0, sizeof(ctx->ftemp));
  ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
  ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
  ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
@@ -1244,11 +1233,6 @@ static void riscv_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
  ctx->temp[i] = NULL;
  }
  ctx->ntemp = 0;
-for (i = ctx->nftemp - 1; i >= 0; --i) {
-tcg_temp_free_i64(ctx->ftemp[i]);
-ctx->ftemp[i] = NULL;
-}
-ctx->nftemp = 0;
  
  /* Only the first insn within a TB is allowed to cross a page boundary. */

  if (ctx->base.is_jmp == DISAS_NEXT) {





Re: [PATCH 52/76] target/riscv: Drop temp_new

2023-02-26 Thread liweiwei



On 2023/2/25 17:14, Richard Henderson wrote:

Translators are no longer required to free tcg temporaries,
therefore there's no need to record temps for later freeing.
Replace the few uses with tcg_temp_new.

Signed-off-by: Richard Henderson 


Oh. It's here.

Reviewed-by: Weiwei Li 

Weiwei Li


---
  target/riscv/translate.c  | 30 +--
  target/riscv/insn_trans/trans_rvzfh.c.inc |  2 +-
  2 files changed, 7 insertions(+), 25 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 273e566d66..b5d8080a6f 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -101,11 +101,8 @@ typedef struct DisasContext {
  bool cfg_vta_all_1s;
  target_ulong vstart;
  bool vl_eq_vlmax;
-uint8_t ntemp;
  CPUState *cs;
  TCGv zero;
-/* Space for 3 operands plus 1 extra for address computation. */
-TCGv temp[4];
  /* PointerMasking extension */
  bool pm_mask_enabled;
  bool pm_base_enabled;
@@ -312,12 +309,6 @@ static void gen_goto_tb(DisasContext *ctx, int n, 
target_ulong dest)
   *
   * Further, we may provide an extension for word operations.
   */
-static TCGv temp_new(DisasContext *ctx)
-{
-assert(ctx->ntemp < ARRAY_SIZE(ctx->temp));
-return ctx->temp[ctx->ntemp++] = tcg_temp_new();
-}
-
  static TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend ext)
  {
  TCGv t;
@@ -332,11 +323,11 @@ static TCGv get_gpr(DisasContext *ctx, int reg_num, 
DisasExtend ext)
  case EXT_NONE:
  break;
  case EXT_SIGN:
-t = temp_new(ctx);
+t = tcg_temp_new();
  tcg_gen_ext32s_tl(t, cpu_gpr[reg_num]);
  return t;
  case EXT_ZERO:
-t = temp_new(ctx);
+t = tcg_temp_new();
  tcg_gen_ext32u_tl(t, cpu_gpr[reg_num]);
  return t;
  default:
@@ -364,7 +355,7 @@ static TCGv get_gprh(DisasContext *ctx, int reg_num)
  static TCGv dest_gpr(DisasContext *ctx, int reg_num)
  {
  if (reg_num == 0 || get_olen(ctx) < TARGET_LONG_BITS) {
-return temp_new(ctx);
+return tcg_temp_new();
  }
  return cpu_gpr[reg_num];
  }
@@ -372,7 +363,7 @@ static TCGv dest_gpr(DisasContext *ctx, int reg_num)
  static TCGv dest_gprh(DisasContext *ctx, int reg_num)
  {
  if (reg_num == 0) {
-return temp_new(ctx);
+return tcg_temp_new();
  }
  return cpu_gprh[reg_num];
  }
@@ -575,7 +566,7 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong 
imm)
  /* Compute a canonical address from a register plus offset. */
  static TCGv get_address(DisasContext *ctx, int rs1, int imm)
  {
-TCGv addr = temp_new(ctx);
+TCGv addr = tcg_temp_new();
  TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
  
  tcg_gen_addi_tl(addr, src1, imm);

@@ -593,7 +584,7 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm)
  /* Compute a canonical address from a register plus reg offset. */
  static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs)
  {
-TCGv addr = temp_new(ctx);
+TCGv addr = tcg_temp_new();
  TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
  
  tcg_gen_add_tl(addr, src1, offs);

@@ -1196,8 +1187,6 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
  ctx->misa_mxl_max = env->misa_mxl_max;
  ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
  ctx->cs = cs;
-ctx->ntemp = 0;
-memset(ctx->temp, 0, sizeof(ctx->temp));
  ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
  ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
  ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
@@ -1222,18 +1211,11 @@ static void riscv_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
  DisasContext *ctx = container_of(dcbase, DisasContext, base);
  CPURISCVState *env = cpu->env_ptr;
  uint16_t opcode16 = translator_lduw(env, &ctx->base, ctx->base.pc_next);
-int i;
  
  ctx->ol = ctx->xl;

  decode_opc(env, ctx, opcode16);
  ctx->base.pc_next = ctx->pc_succ_insn;
  
-for (i = ctx->ntemp - 1; i >= 0; --i) {

-tcg_temp_free(ctx->temp[i]);
-ctx->temp[i] = NULL;
-}
-ctx->ntemp = 0;
-
  /* Only the first insn within a TB is allowed to cross a page boundary. */
  if (ctx->base.is_jmp == DISAS_NEXT) {
  if (ctx->itrigger || !is_same_page(&ctx->base, ctx->base.pc_next)) {
diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc 
b/target/riscv/insn_trans/trans_rvzfh.c.inc
index 2ad5716312..5024e6ecab 100644
--- a/target/riscv/insn_trans/trans_rvzfh.c.inc
+++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
@@ -52,7 +52,7 @@ static bool trans_flh(DisasContext *ctx, arg_flh *a)
  decode_save_opc(ctx);
  t0 = get_gpr(ctx, a->rs1, EXT_NONE);
  if (a->imm) {
-TCGv temp = temp_new(ctx);
+TCGv temp = tcg_temp_new();
  tcg_gen_addi_tl

Re: [PATCH 51/76] target/riscv: Drop ftemp_new

2023-02-26 Thread liweiwei



On 2023/2/25 17:14, Richard Henderson wrote:

Translators are no longer required to free tcg temporaries,
therefore there's no need to record temps for later freeing.
Replace the few uses with tcg_temp_new_i64.

Signed-off-by: Richard Henderson 

Reviewed-by: Weiwei Li 

Weiwei Li

---
  target/riscv/translate.c | 24 
  1 file changed, 4 insertions(+), 20 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index f9d5d1097e..273e566d66 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -106,9 +106,6 @@ typedef struct DisasContext {
  TCGv zero;
  /* Space for 3 operands plus 1 extra for address computation. */
  TCGv temp[4];
-/* Space for 4 operands(1 dest and <=3 src) for float point computation */
-TCGv_i64 ftemp[4];
-uint8_t nftemp;
  /* PointerMasking extension */
  bool pm_mask_enabled;
  bool pm_base_enabled;
@@ -431,12 +428,6 @@ static void gen_set_gpr128(DisasContext *ctx, int reg_num, 
TCGv rl, TCGv rh)
  }
  }
  
-static TCGv_i64 ftemp_new(DisasContext *ctx)

-{
-assert(ctx->nftemp < ARRAY_SIZE(ctx->ftemp));
-return ctx->ftemp[ctx->nftemp++] = tcg_temp_new_i64();
-}
-
  static TCGv_i64 get_fpr_hs(DisasContext *ctx, int reg_num)
  {
  if (!ctx->cfg_ptr->ext_zfinx) {
@@ -450,7 +441,7 @@ static TCGv_i64 get_fpr_hs(DisasContext *ctx, int reg_num)
  case MXL_RV32:
  #ifdef TARGET_RISCV32
  {
-TCGv_i64 t = ftemp_new(ctx);
+TCGv_i64 t = tcg_temp_new_i64();
  tcg_gen_ext_i32_i64(t, cpu_gpr[reg_num]);
  return t;
  }
@@ -476,7 +467,7 @@ static TCGv_i64 get_fpr_d(DisasContext *ctx, int reg_num)
  switch (get_xl(ctx)) {
  case MXL_RV32:
  {
-TCGv_i64 t = ftemp_new(ctx);
+TCGv_i64 t = tcg_temp_new_i64();
  tcg_gen_concat_tl_i64(t, cpu_gpr[reg_num], cpu_gpr[reg_num + 1]);
  return t;
  }
@@ -496,12 +487,12 @@ static TCGv_i64 dest_fpr(DisasContext *ctx, int reg_num)
  }
  
  if (reg_num == 0) {

-return ftemp_new(ctx);
+return tcg_temp_new_i64();
  }
  
  switch (get_xl(ctx)) {

  case MXL_RV32:
-return ftemp_new(ctx);
+return tcg_temp_new_i64();
  #ifdef TARGET_RISCV64
  case MXL_RV64:
  return cpu_gpr[reg_num];
@@ -1207,8 +1198,6 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
  ctx->cs = cs;
  ctx->ntemp = 0;
  memset(ctx->temp, 0, sizeof(ctx->temp));
-ctx->nftemp = 0;
-memset(ctx->ftemp, 0, sizeof(ctx->ftemp));
  ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
  ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
  ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
@@ -1244,11 +1233,6 @@ static void riscv_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
  ctx->temp[i] = NULL;
  }
  ctx->ntemp = 0;
-for (i = ctx->nftemp - 1; i >= 0; --i) {
-tcg_temp_free_i64(ctx->ftemp[i]);
-ctx->ftemp[i] = NULL;
-}
-ctx->nftemp = 0;
  
  /* Only the first insn within a TB is allowed to cross a page boundary. */

  if (ctx->base.is_jmp == DISAS_NEXT) {





Re: [PATCH qemu] timer/i8254: Fix one shot PIT mode

2023-02-26 Thread Michael S. Tsirkin
On Sun, Feb 26, 2023 at 01:11:19PM +0100, BALATON Zoltan wrote:
> On Sun, 26 Feb 2023, Max Filippov wrote:
> > On Sun, Feb 26, 2023 at 1:18 AM Damien Zammit  wrote:
> > > 
> > > Hi Michael,
> > > 
> > > Thanks for reviewing this on a weekend!
> > > 
> > > On 26/2/23 19:51, Michael S. Tsirkin wrote:
> > > > On Sun, Feb 26, 2023 at 01:58:10AM +, Damien Zammit wrote:
> > > > >   case 0:
> > > > > -out = (d >= s->count);
> > > > > -break;
> > > > 
> > > > 
> > > > I think you need something like
> > > >   /* FALLTHRU */
> > > > here otherwise some gcc versions will warn.
> > > > 
> > > > >   case 1:
> > > > > -out = (d < s->count);
> > > > > +out = (d >= s->count);
> > > 
> > > It seems that there are quite a number of these consecutive fallthrough 
> > > cases
> > > without /* FALLTHRU */ in i8254_common.c
> > > 
> > > Can these be fixed in a separate patch?
> > 
> > I believe that the comment is only needed when there's code
> > between the labels and is not needed between the labels that
> > follow each other.
> 
> I think so too, I have some of these consecutive case labels in my code and
> never had a problem with that. Only when you have a statement between labels
> without break is when a comment is needed.
> 
> Regards,
> BALATON Zoltan


I just tried and it looks like you are right. Pls ignore sorry about the
noise.

-- 
MST




Re: [PATCH 53/76] target/riscv: Drop tcg_temp_free

2023-02-26 Thread liweiwei



On 2023/2/25 17:14, Richard Henderson wrote:

Translators are no longer required to free tcg temporaries.

Signed-off-by: Richard Henderson 

Reviewed-by: Weiwei Li 

Weiwei Li

---
  target/riscv/translate.c   |  7 ---
  target/riscv/insn_trans/trans_rvb.c.inc| 24 --
  target/riscv/insn_trans/trans_rvd.c.inc|  2 -
  target/riscv/insn_trans/trans_rvf.c.inc|  9 
  target/riscv/insn_trans/trans_rvi.c.inc| 37 ---
  target/riscv/insn_trans/trans_rvk.c.inc| 15 --
  target/riscv/insn_trans/trans_rvm.c.inc| 33 -
  target/riscv/insn_trans/trans_rvv.c.inc| 55 --
  target/riscv/insn_trans/trans_rvzfh.c.inc  | 10 
  target/riscv/insn_trans/trans_xthead.c.inc | 24 +-
  10 files changed, 1 insertion(+), 215 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b5d8080a6f..180fa5d30d 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -205,8 +205,6 @@ static void gen_check_nanbox_h(TCGv_i64 out, TCGv_i64 in)
  TCGv_i64 t_nan = tcg_const_i64(0x7e00ull);
  
  tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);

-tcg_temp_free_i64(t_max);
-tcg_temp_free_i64(t_nan);
  }
  
  static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)

@@ -621,7 +619,6 @@ static void mark_fs_dirty(DisasContext *ctx)
  tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
  tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
  tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
-tcg_temp_free(tmp);
  }
  
  if (ctx->virt_enabled && ctx->mstatus_hs_fs != MSTATUS_FS) {

@@ -632,7 +629,6 @@ static void mark_fs_dirty(DisasContext *ctx)
  tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
  tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
  tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
-tcg_temp_free(tmp);
  }
  }
  #else
@@ -657,7 +653,6 @@ static void mark_vs_dirty(DisasContext *ctx)
  tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
  tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS);
  tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
-tcg_temp_free(tmp);
  }
  
  if (ctx->virt_enabled && ctx->mstatus_hs_vs != MSTATUS_VS) {

@@ -668,7 +663,6 @@ static void mark_vs_dirty(DisasContext *ctx)
  tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
  tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS);
  tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
-tcg_temp_free(tmp);
  }
  }
  #else
@@ -1019,7 +1013,6 @@ static bool gen_shift(DisasContext *ctx, arg_r *a, 
DisasExtend ext,
  f128(dest, desth, src1, src1h, ext2);
  gen_set_gpr128(ctx, a->rd, dest, desth);
  }
-tcg_temp_free(ext2);
  return true;
  }
  
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc

index 990bc94b98..e4dcc7c991 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -64,7 +64,6 @@ static void gen_clzw(TCGv ret, TCGv arg1)
  TCGv t = tcg_temp_new();
  tcg_gen_shli_tl(t, arg1, 32);
  tcg_gen_clzi_tl(ret, t, 32);
-tcg_temp_free(t);
  }
  
  static bool trans_clz(DisasContext *ctx, arg_clz *a)

@@ -161,8 +160,6 @@ static void gen_bset(TCGv ret, TCGv arg1, TCGv shamt)
  
  gen_sbop_mask(t, shamt);

  tcg_gen_or_tl(ret, arg1, t);
-
-tcg_temp_free(t);
  }
  
  static bool trans_bset(DisasContext *ctx, arg_bset *a)

@@ -183,8 +180,6 @@ static void gen_bclr(TCGv ret, TCGv arg1, TCGv shamt)
  
  gen_sbop_mask(t, shamt);

  tcg_gen_andc_tl(ret, arg1, t);
-
-tcg_temp_free(t);
  }
  
  static bool trans_bclr(DisasContext *ctx, arg_bclr *a)

@@ -205,8 +200,6 @@ static void gen_binv(TCGv ret, TCGv arg1, TCGv shamt)
  
  gen_sbop_mask(t, shamt);

  tcg_gen_xor_tl(ret, arg1, t);
-
-tcg_temp_free(t);
  }
  
  static bool trans_binv(DisasContext *ctx, arg_binv *a)

@@ -252,9 +245,6 @@ static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2)
  
  /* sign-extend 64-bits */

  tcg_gen_ext_i32_tl(ret, t1);
-
-tcg_temp_free_i32(t1);
-tcg_temp_free_i32(t2);
  }
  
  static bool trans_ror(DisasContext *ctx, arg_ror *a)

@@ -270,8 +260,6 @@ static void gen_roriw(TCGv ret, TCGv arg1, target_long 
shamt)
  tcg_gen_trunc_tl_i32(t1, arg1);
  tcg_gen_rotri_i32(t1, t1, shamt);
  tcg_gen_ext_i32_tl(ret, t1);
-
-tcg_temp_free_i32(t1);
  }
  
  static bool trans_rori(DisasContext *ctx, arg_rori *a)

@@ -294,9 +282,6 @@ static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2)
  
  /* sign-extend 64-bits */

  tcg_gen_ext_i32_tl(ret, t1);
-
-tcg_temp_free_i32(t1);
-tcg_temp_free_i32(t2);
  }
  
  static bool trans_rol(DisasContext *ctx, arg_rol *a)

@@ -340,8 +325,6 @@ static void gen_orc_b(TCGv r

Re: [PATCH v4] audio/pwaudio.c: Add Pipewire audio backend for QEMU

2023-02-26 Thread Marc-André Lureau
Hi

On Fri, Feb 17, 2023 at 9:08 PM Dorinda Bassey  wrote:
>
> This commit adds a new audiodev backend to allow QEMU to use Pipewire as
> both an audio sink and source. This backend is available on most systems
>
> Add Pipewire entry points for QEMU Pipewire audio backend
> Add wrappers for QEMU Pipewire audio backend in qpw_pcm_ops()
> qpw_write function returns the current state of the stream to pwaudio
> and Writes some data to the server for playback streams using pipewire
> spa_ringbuffer implementation.
> qpw_read function returns the current state of the stream to pwaudio and
> reads some data from the server for capture streams using pipewire
> spa_ringbuffer implementation. These functions qpw_write and qpw_read
> are called during playback and capture.
> Added some functions that convert pw audio formats to QEMU audio format
> and vice versa which would be needed in the pipewire audio sink and
> source functions qpw_init_in() & qpw_init_out().
> These methods that implement playback and recording will create streams
> for playback and capture that will start processing and will result in
> the on_process callbacks to be called.
> Built a connection to the Pipewire sound system server in the
> qpw_audio_init() method.
>
> Signed-off-by: Dorinda Bassey 

pipewire: Initialize PW context
stream state: "connecting"
stream state: "connecting"
stream state: "paused"
node id: 125
stream state: "paused"
node id: 142
stream state: "streaming"
stream state: "streaming"

Can you make it a bit silent? Probably all AUD_log() & printf*( should
be replaced by trace.

Playback works for me, however recording is failing. I haven't
investigated, is it working for you?

> ---
> fix typo
> raise version dependency
>
>  audio/audio.c |   3 +
>  audio/audio_template.h|   4 +
>  audio/meson.build |   1 +
>  audio/pwaudio.c   | 827 ++
>  meson.build   |   8 +
>  meson_options.txt |   4 +-
>  qapi/audio.json   |  45 ++
>  qemu-options.hx   |  17 +
>  scripts/meson-buildoptions.sh |   8 +-
>  9 files changed, 914 insertions(+), 3 deletions(-)
>  create mode 100644 audio/pwaudio.c
>
> diff --git a/audio/audio.c b/audio/audio.c
> index 4290309d18..aa55e41ad8 100644
> --- a/audio/audio.c
> +++ b/audio/audio.c
> @@ -2069,6 +2069,9 @@ void audio_create_pdos(Audiodev *dev)
>  #ifdef CONFIG_AUDIO_PA
>  CASE(PA, pa, Pa);
>  #endif
> +#ifdef CONFIG_AUDIO_PIPEWIRE
> +CASE(PIPEWIRE, pipewire, Pipewire);
> +#endif
>  #ifdef CONFIG_AUDIO_SDL
>  CASE(SDL, sdl, Sdl);
>  #endif
> diff --git a/audio/audio_template.h b/audio/audio_template.h
> index 42b4712acb..0f02afb921 100644
> --- a/audio/audio_template.h
> +++ b/audio/audio_template.h
> @@ -355,6 +355,10 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, 
> TYPE)(Audiodev *dev)
>  case AUDIODEV_DRIVER_PA:
>  return qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.TYPE);
>  #endif
> +#ifdef CONFIG_AUDIO_PIPEWIRE
> +case AUDIODEV_DRIVER_PIPEWIRE:
> +return 
> qapi_AudiodevPipewirePerDirectionOptions_base(dev->u.pipewire.TYPE);
> +#endif
>  #ifdef CONFIG_AUDIO_SDL
>  case AUDIODEV_DRIVER_SDL:
>  return qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.TYPE);
> diff --git a/audio/meson.build b/audio/meson.build
> index 074ba9..65a49c1a10 100644
> --- a/audio/meson.build
> +++ b/audio/meson.build
> @@ -19,6 +19,7 @@ foreach m : [
>['sdl', sdl, files('sdlaudio.c')],
>['jack', jack, files('jackaudio.c')],
>['sndio', sndio, files('sndioaudio.c')],
> +  ['pipewire', pipewire, files('pwaudio.c')],
>['spice', spice, files('spiceaudio.c')]
>  ]
>if m[1].found()
> diff --git a/audio/pwaudio.c b/audio/pwaudio.c
> new file mode 100644
> index 00..aa22f40a80
> --- /dev/null
> +++ b/audio/pwaudio.c
> @@ -0,0 +1,827 @@
> +/*
> + * QEMU Pipewire audio driver
> + *
> + * Copyright (c) 2023 Red Hat Inc.
> + *
> + * Author: Dorinda Bassey   
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a 
> copy
> + * of this software and associated documentation files (the "Software"), to 
> deal
> + * in the Software without restriction, including without limitation the 
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
>

Re: [PATCH v2 03/20] vfio/migration: Add VFIO migration pre-copy support

2023-02-26 Thread Avihai Horon



On 23/02/2023 23:16, Alex Williamson wrote:

External email: Use caution opening links or attachments


On Thu, 23 Feb 2023 17:25:12 +0200
Avihai Horon  wrote:


On 22/02/2023 22:58, Alex Williamson wrote:

External email: Use caution opening links or attachments


On Wed, 22 Feb 2023 19:48:58 +0200
Avihai Horon  wrote:


@@ -302,23 +380,44 @@ static void vfio_save_cleanup(void *opaque)
   trace_vfio_save_cleanup(vbasedev->name);
   }

+static void vfio_state_pending_estimate(void *opaque, uint64_t threshold_size,
+uint64_t *must_precopy,
+uint64_t *can_postcopy)
+{
+VFIODevice *vbasedev = opaque;
+VFIOMigration *migration = vbasedev->migration;
+
+if (migration->device_state != VFIO_DEVICE_STATE_PRE_COPY) {
+return;
+}
+
+/*
+ * Initial size should be transferred during pre-copy phase so stop-copy
+ * phase will not be slowed down. Report threshold_size to force another
+ * pre-copy iteration.
+ */
+*must_precopy += migration->precopy_init_size ?
+ threshold_size :
+ migration->precopy_dirty_size;

This sure feels like we're feeding false data back to the iterator to
spoof it to run another iteration, when the vfio migration protocol
only recommends that initial_bytes reaches zero before proceeding to
stop-copy, it's not a requirement.  What benefit is actually observed
from this?  Why is this required for initial pre-copy support?  It
seems devious.

As previously discussed in the thread that added the pre-copy uAPI [1],
the init_bytes can be used by drivers to reduce the downtime.
For example, mlx5 transfers some metadata to the target so it will be
able to pre-allocate resources etc.

[1]
https://lore.kernel.org/kvm/ae4a6259-349d-0131-896c-7a6ea775c...@nvidia.com/

Yes, but how does that become a requirement to QEMU that it must
iterate until the initial segment is complete?  Especially when we need
to trigger that behavior via such nefarious means.  AIUI, QEMU should
be allowed to move to stop-copy at any point.  We should make efforts
that QEMU would never decide on its own to move from pre-copy to
stop-copy without completing the init_bytes (which sounds suspiciously
like the purpose of @must_precopy),


@must_precopy represents the pending bytes that must be transferred 
during pre-copy or stop-copy. If it's under the threshold, then 
migration will move to stop-copy and be completed.
So simply adding init_bytes to @must_precopy will not guarantee that we 
send all init_bytes before moving to stop-copy, since the transition to 
stop-copy can happen when @must_precopy != 0.



  but if, for instance a user forces a
transition to stop-copy, I don't see that we have any business to
impose a policy to delay that until the init_bytes is complete.


Is there a way a user can force the migration to move to stop-copy?
Looking at migration code, it seems that the only way to move to 
stop-copy is if @must_precopy is below the threshold.
If so, then this is our effort to make QEMU send all init_bytes before 
moving to stop_copy and we can only benefit from it.


Regarding how to do it -- maybe instead of spoofing @must_precopy we can 
introduce a new parameter in upper migration layer (e.g., @init_precopy) 
and add another condition in migration layer that it must be zero to 
move to stop-copy.


Thanks.




Re: [PATCH v2 11/20] vfio/common: Add device dirty page tracking start/stop

2023-02-26 Thread Avihai Horon



On 23/02/2023 22:54, Jason Gunthorpe wrote:

On Thu, Feb 23, 2023 at 01:16:40PM -0700, Alex Williamson wrote:

On Thu, 23 Feb 2023 15:30:28 -0400
Jason Gunthorpe  wrote:


On Thu, Feb 23, 2023 at 12:27:23PM -0700, Alex Williamson wrote:

So again, I think I'm just looking for a better comment that doesn't
add FUD to the reasoning behind switching to a single range,

It isn't a single range, it is a single page of ranges, right?

Exceeding a single page of ranges is the inflection point at which we
switch to a single range.

Oh, that isn't what it should do - it should cut it back to fit in a
page..


Sure, I will change it accordingly (and rephrase the comment).

Thanks.




Re: [PATCH v2 00/20] vfio: Add migration pre-copy support and device dirty tracking

2023-02-26 Thread Avihai Horon



On 24/02/2023 21:26, Joao Martins wrote:

External email: Use caution opening links or attachments


On 23/02/2023 14:56, Avihai Horon wrote:

On 22/02/2023 22:55, Alex Williamson wrote:

There are various errors running this through the CI on gitlab.

This one seems bogus but needs to be resolved regardless:

https://gitlab.com/alex.williamson/qemu/-/jobs/3817940731
FAILED: libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o
2786s390x-linux-gnu-gcc -m64 -Ilibqemu-aarch64-softmmu.fa.p -I. -I..
-Itarget/arm -I../target/arm -Iqapi -Itrace -Iui -Iui/shader
-I/usr/include/pixman-1 -I/usr/include/capstone -I/usr/include/glib-2.0
-I/usr/lib/s390x-linux-gnu/glib-2.0/include -fdiagnostics-color=auto -Wall
-Winvalid-pch -Werror -std=gnu11 -O2 -g -isystem
/builds/alex.williamson/qemu/linux-headers -isystem linux-headers -iquote .
-iquote /builds/alex.williamson/qemu -iquote
/builds/alex.williamson/qemu/include -iquote
/builds/alex.williamson/qemu/tcg/s390x -pthread -U_FORTIFY_SOURCE
-D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-fno-strict-aliasing -fno-common -fwrapv -Wundef -Wwrite-strings
-Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls
-Wold-style-declaration -Wold-style-definition -Wtype-limits -Wformat-security
-Wformat-y2k -Winit-self -Wignored-qualifiers -Wempty-body -Wnested-externs
-Wendif-labels -Wexpansion-to-defined -Wimplicit-fallthrough=2
-Wmissing-format-attribute -Wno-missing-include-dirs -Wno-shift-negative-value
-Wno-psabi -fstack-protector-strong -fPIE -isystem../linux-headers
-isystemlinux-headers -DNEED_CPU_H
'-DCONFIG_TARGET="aarch64-softmmu-config-target.h"'
'-DCONFIG_DEVICES="aarch64-softmmu-config-devices.h"' -MD -MQ
libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o -MF
libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o.d -o
libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o -c ../hw/vfio/common.c
2787../hw/vfio/common.c: In function ‘vfio_listener_log_global_start’:
2788../hw/vfio/common.c:1772:8: error: ‘ret’ may be used uninitialized in this
function [-Werror=maybe-uninitialized]
2789 1772 | if (ret) {
2790  |    ^

32-bit builds have some actual errors though:

https://gitlab.com/alex.williamson/qemu/-/jobs/3817940719
FAILED: libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o
2601cc -m32 -Ilibqemu-aarch64-softmmu.fa.p -I. -I.. -Itarget/arm
-I../target/arm -Iqapi -Itrace -Iui -Iui/shader -I/usr/include/pixman-1
-I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/sysprof-4
-fdiagnostics-color=auto -Wall -Winvalid-pch -Werror -std=gnu11 -O2 -g
-isystem /builds/alex.williamson/qemu/linux-headers -isystem linux-headers
-iquote . -iquote /builds/alex.williamson/qemu -iquote
/builds/alex.williamson/qemu/include -iquote
/builds/alex.williamson/qemu/tcg/i386 -pthread -U_FORTIFY_SOURCE
-D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-fno-strict-aliasing -fno-common -fwrapv -Wundef -Wwrite-strings
-Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls
-Wold-style-declaration -Wold-style-definition -Wtype-limits -Wformat-security
-Wformat-y2k -Winit-self -Wignored-qualifiers -Wempty-body -Wnested-externs
-Wendif-labels -Wexpansion-to-defined -Wimplicit-fallthrough=2
-Wmissing-format-attribute -Wno-missing-include-dirs -Wno-shift-negative-value
-Wno-psabi -fstack-protector-strong -fPIE -isystem../linux-headers
-isystemlinux-headers -DNEED_CPU_H
'-DCONFIG_TARGET="aarch64-softmmu-config-target.h"'
'-DCONFIG_DEVICES="aarch64-softmmu-config-devices.h"' -MD -MQ
libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o -MF
libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o.d -o
libqemu-aarch64-softmmu.fa.p/hw_vfio_common.c.o -c ../hw/vfio/common.c
2602../hw/vfio/common.c: In function
'vfio_device_feature_dma_logging_start_create':
2603../hw/vfio/common.c:1572:27: error: cast from pointer to integer of
different size [-Werror=pointer-to-int-cast]
2604 1572 |     control->ranges = (uint64_t)ranges;
2605  |   ^
2606../hw/vfio/common.c:1596:23: error: cast from pointer to integer of
different size [-Werror=pointer-to-int-cast]
2607 1596 | control->ranges = (uint64_t)ranges;
2608  |   ^
2609../hw/vfio/common.c: In function
'vfio_device_feature_dma_logging_start_destroy':
2610../hw/vfio/common.c:1620:9: error: cast to pointer from integer of
different size [-Werror=int-to-pointer-cast]
2611 1620 | (struct vfio_device_feature_dma_logging_range
*)control->ranges;
2612  | ^
2613../hw/vfio/common.c: In function 'vfio_device_dma_logging_report':
2614../hw/vfio/common.c:1810:22: error: cast from pointer to integer of
different size [-Werror=pointer-to-int-cast]
2615 1810 | report->bitmap = (uint64_t)bitmap;
2616  |  ^

Sure, I will fix these errors.

Just a thought: should the pre-copy series be moved towards the end of this
series, given that it's more of an improvement of downtime than a must-have like
dirty tracking?


Given recent d

[PATCH 1/2] target/riscv/vector_helper.c: create vext_set_tail_elems_1s()

2023-02-26 Thread Daniel Henrique Barboza
Commit 752614cab8e6 ("target/riscv: rvv: Add tail agnostic for vector
load / store instructions") added code to set the tail elements to 1 in
the end of vext_ldst_stride(), vext_ldst_us(), vext_ldst_index() and
vext_ldff(). Aside from a env->vl versus an evl value being used in the
first loop, the code is being repeated 4 times.

Create a helper to avoid code repetition in all those functions.
Arguments that are used in the callers (nf, esz and max_elems) are
passed as arguments. All other values are being derived inside the
helper.

Reviewed-by: Weiwei Li 
Reviewed-by: Frank Chang 
Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/vector_helper.c | 86 +---
 1 file changed, 30 insertions(+), 56 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 00de879787..7d2e3978f1 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -267,6 +267,28 @@ GEN_VEXT_ST_ELEM(ste_h, int16_t, H2, stw)
 GEN_VEXT_ST_ELEM(ste_w, int32_t, H4, stl)
 GEN_VEXT_ST_ELEM(ste_d, int64_t, H8, stq)
 
+static void vext_set_tail_elems_1s(CPURISCVState *env, target_ulong vl,
+   void *vd, uint32_t desc, uint32_t nf,
+   uint32_t esz, uint32_t max_elems)
+{
+uint32_t total_elems = vext_get_total_elems(env, desc, esz);
+uint32_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
+uint32_t vta = vext_vta(desc);
+uint32_t registers_used;
+int k;
+
+for (k = 0; k < nf; ++k) {
+vext_set_elems_1s(vd, vta, (k * max_elems + vl) * esz,
+  (k * max_elems + max_elems) * esz);
+}
+
+if (nf * max_elems % total_elems != 0) {
+registers_used = ((nf * max_elems) * esz + (vlenb - 1)) / vlenb;
+vext_set_elems_1s(vd, vta, (nf * max_elems) * esz,
+  registers_used * vlenb);
+}
+}
+
 /*
  *** stride: access vector element from strided memory
  */
@@ -281,8 +303,6 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
 uint32_t nf = vext_nf(desc);
 uint32_t max_elems = vext_max_elems(desc, log2_esz);
 uint32_t esz = 1 << log2_esz;
-uint32_t total_elems = vext_get_total_elems(env, desc, esz);
-uint32_t vta = vext_vta(desc);
 uint32_t vma = vext_vma(desc);
 
 for (i = env->vstart; i < env->vl; i++, env->vstart++) {
@@ -301,18 +321,8 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
 }
 }
 env->vstart = 0;
-/* set tail elements to 1s */
-for (k = 0; k < nf; ++k) {
-vext_set_elems_1s(vd, vta, (k * max_elems + env->vl) * esz,
-  (k * max_elems + max_elems) * esz);
-}
-if (nf * max_elems % total_elems != 0) {
-uint32_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
-uint32_t registers_used =
-((nf * max_elems) * esz + (vlenb - 1)) / vlenb;
-vext_set_elems_1s(vd, vta, (nf * max_elems) * esz,
-  registers_used * vlenb);
-}
+
+vext_set_tail_elems_1s(env, env->vl, vd, desc, nf, esz, max_elems);
 }
 
 #define GEN_VEXT_LD_STRIDE(NAME, ETYPE, LOAD_FN)\
@@ -359,8 +369,6 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState 
*env, uint32_t desc,
 uint32_t nf = vext_nf(desc);
 uint32_t max_elems = vext_max_elems(desc, log2_esz);
 uint32_t esz = 1 << log2_esz;
-uint32_t total_elems = vext_get_total_elems(env, desc, esz);
-uint32_t vta = vext_vta(desc);
 
 /* load bytes from guest memory */
 for (i = env->vstart; i < evl; i++, env->vstart++) {
@@ -372,18 +380,8 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState 
*env, uint32_t desc,
 }
 }
 env->vstart = 0;
-/* set tail elements to 1s */
-for (k = 0; k < nf; ++k) {
-vext_set_elems_1s(vd, vta, (k * max_elems + evl) * esz,
-  (k * max_elems + max_elems) * esz);
-}
-if (nf * max_elems % total_elems != 0) {
-uint32_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
-uint32_t registers_used =
-((nf * max_elems) * esz + (vlenb - 1)) / vlenb;
-vext_set_elems_1s(vd, vta, (nf * max_elems) * esz,
-  registers_used * vlenb);
-}
+
+vext_set_tail_elems_1s(env, evl, vd, desc, nf, esz, max_elems);
 }
 
 /*
@@ -484,8 +482,6 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
 uint32_t vm = vext_vm(desc);
 uint32_t max_elems = vext_max_elems(desc, log2_esz);
 uint32_t esz = 1 << log2_esz;
-uint32_t total_elems = vext_get_total_elems(env, desc, esz);
-uint32_t vta = vext_vta(desc);
 uint32_t vma = vext_vma(desc);
 
 /* load bytes from guest memory */
@@ -505,18 +501,8 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
 }
 }
 env->vstart = 0;
-/* set tail elements to 1s */
-for (k = 0; k < nf; ++k) {
-vext_set_elems_1s(vd, vta, (k * max_elems + env->vl) * esz,
-   

[PATCH 2/2] target/riscv/vector_helper.c: avoid env_archcpu() when reading RISCVCPUConfig

2023-02-26 Thread Daniel Henrique Barboza
This file has several uses of env_archcpu() that are used solely to read
cfg->vlen. Use the new riscv_cpu_cfg() inline instead.

Suggested-by: Weiwei Li 
Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/vector_helper.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 7d2e3978f1..a7fb09efa3 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -272,7 +272,7 @@ static void vext_set_tail_elems_1s(CPURISCVState *env, 
target_ulong vl,
uint32_t esz, uint32_t max_elems)
 {
 uint32_t total_elems = vext_get_total_elems(env, desc, esz);
-uint32_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
+uint32_t vlenb = riscv_cpu_cfg(env)->vlen >> 3;
 uint32_t vta = vext_vta(desc);
 uint32_t registers_used;
 int k;
@@ -671,7 +671,7 @@ vext_ldst_whole(void *vd, target_ulong base, CPURISCVState 
*env, uint32_t desc,
 {
 uint32_t i, k, off, pos;
 uint32_t nf = vext_nf(desc);
-uint32_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
+uint32_t vlenb = riscv_cpu_cfg(env)->vlen >> 3;
 uint32_t max_elems = vlenb >> log2_esz;
 
 k = env->vstart / max_elems;
@@ -1141,7 +1141,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 { \
 uint32_t vl = env->vl;\
 uint32_t vm = vext_vm(desc);  \
-uint32_t total_elems = env_archcpu(env)->cfg.vlen;\
+uint32_t total_elems = riscv_cpu_cfg(env)->vlen;  \
 uint32_t vta_all_1s = vext_vta_all_1s(desc);  \
 uint32_t i;   \
   \
@@ -1177,7 +1177,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1,
  \
 {   \
 uint32_t vl = env->vl;  \
 uint32_t vm = vext_vm(desc);\
-uint32_t total_elems = env_archcpu(env)->cfg.vlen;  \
+uint32_t total_elems = riscv_cpu_cfg(env)->vlen;\
 uint32_t vta_all_1s = vext_vta_all_1s(desc);\
 uint32_t i; \
 \
@@ -1376,7 +1376,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 { \
 uint32_t vm = vext_vm(desc);  \
 uint32_t vl = env->vl;\
-uint32_t total_elems = env_archcpu(env)->cfg.vlen;\
+uint32_t total_elems = riscv_cpu_cfg(env)->vlen;  \
 uint32_t vta_all_1s = vext_vta_all_1s(desc);  \
 uint32_t vma = vext_vma(desc);\
 uint32_t i;   \
@@ -1439,7 +1439,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2,   \
 {   \
 uint32_t vm = vext_vm(desc);\
 uint32_t vl = env->vl;  \
-uint32_t total_elems = env_archcpu(env)->cfg.vlen;  \
+uint32_t total_elems = riscv_cpu_cfg(env)->vlen;\
 uint32_t vta_all_1s = vext_vta_all_1s(desc);\
 uint32_t vma = vext_vma(desc);  \
 uint32_t i; \
@@ -4152,7 +4152,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 { \
 uint32_t vm = vext_vm(desc);  \
 uint32_t vl = env->vl;\
-uint32_t total_elems = env_archcpu(env)->cfg.vlen;\
+uint32_t total_elems = riscv_cpu_cfg(env)->vlen;  \
 uint32_t vta_all_1s = vext_vta_all_1s(desc);  \
 uint32_t vma = vext_vma(desc);\
 uint32_t i;   \
@@ -4190,7 +4190,7 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void 
*vs2,   \
 {   \
 uint32_t vm = vext_vm(desc);\
 uint32_t vl = env->vl;  \
-uint32_t total_elems = env_archcpu(env)->cfg.vlen;  \
+uint32_t total_elems = riscv_cpu_cfg(env)->vlen;\
 uint32_t vta_all_1s = vext_vta_all_1s(desc);\
 uint32_t vma = vext_vma(desc);  \
 uint32_t i;  

[PATCH 0/2] target/riscv: some vector_helper.c cleanups

2023-02-26 Thread Daniel Henrique Barboza
Based-on: 20230222185205.355361-2-dbarb...@ventanamicro.com
("[PATCH v7 01/10] target/riscv: introduce riscv_cpu_cfg()")

Hi,

This is a re-send of patch 1, which is already reviewed, with a
follow-up that uses riscv_cpu_cfg() in the remaining of the file. This
was suggested by Weiwei Li in the "[PATCH 0/4] RISCVCPUConfig related
cleanups" review. Patch 1 makes the work of patch 2 easier since it
eliminated some uses of env_archcpu() we want to avoid.

Both patches depends on patch "[PATCH v7 01/10] target/riscv: introduce
riscv_cpu_cfg()" that can be found here:

https://patchew.org/QEMU/20230222185205.355361-1-dbarb...@ventanamicro.com/20230222185205.355361-2-dbarb...@ventanamicro.com/


Daniel Henrique Barboza (2):
  target/riscv/vector_helper.c: create vext_set_tail_elems_1s()
  target/riscv/vector_helper.c: avoid env_archcpu() when reading
RISCVCPUConfig

 target/riscv/vector_helper.c | 104 +--
 1 file changed, 39 insertions(+), 65 deletions(-)

-- 
2.39.2




Re: [PATCH 0/4] RISCVCPUConfig related cleanups

2023-02-26 Thread Daniel Henrique Barboza




On 2/25/23 03:47, liweiwei wrote:


On 2023/2/25 01:45, Daniel Henrique Barboza wrote:

Hi,

These cleanups were suggested by LIU Zhiwei during the review of the
RISCV_FEATURE_* cleanups, currently on version 7 [1].

These are dependent on the patch "[PATCH v7 01/10] target/riscv: introduce
riscv_cpu_cfg()" from [1] because we use the riscv_cpu_cfg() API.


[1] https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg06467.html

Daniel Henrique Barboza (4):
   target/riscv/csr.c: use env_archcpu() in ctr()
   target/riscv/csr.c: simplify mctr()
   target/riscv/csr.c: use riscv_cpu_cfg() to avoid env_cpu() pointers
   target/riscv/csr.c: avoid env_archcpu() usages when reading
 RISCVCPUConfig

  target/riscv/csr.c | 90 +-
  1 file changed, 24 insertions(+), 66 deletions(-)


As  I suggested in another patch, cpu_get_cfg() can also be used in 
vector_helper.c.



I decided to do it in a separated series together with the vector_helper.c 
change
I did last week:


https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg07566.html


The vector_change I did prior eliminated some of the env_archcpu() we want to
avoid so makes sense to one after the other.


Thanks,


Daniel




Regards,

Weiwei Li






Re: [PATCH] target/riscv/vector_helper.c: create vext_set_tail_elems_1s()

2023-02-26 Thread Daniel Henrique Barboza

Thanks for the reviews!


I decided to take this patch (acks included) and send it in together with
a cleanup of the env_archcpu() usages in vector_helper.c:


https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg07566.html



Thanks,


Daniel

On 2/21/23 15:45, Daniel Henrique Barboza wrote:

Commit 752614cab8e6 ("target/riscv: rvv: Add tail agnostic for vector
load / store instructions") added code to set the tail elements to 1 in
the end of vext_ldst_stride(), vext_ldst_us(), vext_ldst_index() and
vext_ldff(). Aside from a env->vl versus an evl value being used in the
first loop, the code is being repeated 4 times.

Create a helper to avoid code repetition in all those functions.
Arguments that are used in the callers (nf, esz and max_elems) are
passed as arguments. All other values are being derived inside the
helper.

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

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 00de879787..7d2e3978f1 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -267,6 +267,28 @@ GEN_VEXT_ST_ELEM(ste_h, int16_t, H2, stw)
  GEN_VEXT_ST_ELEM(ste_w, int32_t, H4, stl)
  GEN_VEXT_ST_ELEM(ste_d, int64_t, H8, stq)
  
+static void vext_set_tail_elems_1s(CPURISCVState *env, target_ulong vl,

+   void *vd, uint32_t desc, uint32_t nf,
+   uint32_t esz, uint32_t max_elems)
+{
+uint32_t total_elems = vext_get_total_elems(env, desc, esz);
+uint32_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
+uint32_t vta = vext_vta(desc);
+uint32_t registers_used;
+int k;
+
+for (k = 0; k < nf; ++k) {
+vext_set_elems_1s(vd, vta, (k * max_elems + vl) * esz,
+  (k * max_elems + max_elems) * esz);
+}
+
+if (nf * max_elems % total_elems != 0) {
+registers_used = ((nf * max_elems) * esz + (vlenb - 1)) / vlenb;
+vext_set_elems_1s(vd, vta, (nf * max_elems) * esz,
+  registers_used * vlenb);
+}
+}
+
  /*
   *** stride: access vector element from strided memory
   */
@@ -281,8 +303,6 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
  uint32_t nf = vext_nf(desc);
  uint32_t max_elems = vext_max_elems(desc, log2_esz);
  uint32_t esz = 1 << log2_esz;
-uint32_t total_elems = vext_get_total_elems(env, desc, esz);
-uint32_t vta = vext_vta(desc);
  uint32_t vma = vext_vma(desc);
  
  for (i = env->vstart; i < env->vl; i++, env->vstart++) {

@@ -301,18 +321,8 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
  }
  }
  env->vstart = 0;
-/* set tail elements to 1s */
-for (k = 0; k < nf; ++k) {
-vext_set_elems_1s(vd, vta, (k * max_elems + env->vl) * esz,
-  (k * max_elems + max_elems) * esz);
-}
-if (nf * max_elems % total_elems != 0) {
-uint32_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
-uint32_t registers_used =
-((nf * max_elems) * esz + (vlenb - 1)) / vlenb;
-vext_set_elems_1s(vd, vta, (nf * max_elems) * esz,
-  registers_used * vlenb);
-}
+
+vext_set_tail_elems_1s(env, env->vl, vd, desc, nf, esz, max_elems);
  }
  
  #define GEN_VEXT_LD_STRIDE(NAME, ETYPE, LOAD_FN)\

@@ -359,8 +369,6 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState 
*env, uint32_t desc,
  uint32_t nf = vext_nf(desc);
  uint32_t max_elems = vext_max_elems(desc, log2_esz);
  uint32_t esz = 1 << log2_esz;
-uint32_t total_elems = vext_get_total_elems(env, desc, esz);
-uint32_t vta = vext_vta(desc);
  
  /* load bytes from guest memory */

  for (i = env->vstart; i < evl; i++, env->vstart++) {
@@ -372,18 +380,8 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState 
*env, uint32_t desc,
  }
  }
  env->vstart = 0;
-/* set tail elements to 1s */
-for (k = 0; k < nf; ++k) {
-vext_set_elems_1s(vd, vta, (k * max_elems + evl) * esz,
-  (k * max_elems + max_elems) * esz);
-}
-if (nf * max_elems % total_elems != 0) {
-uint32_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
-uint32_t registers_used =
-((nf * max_elems) * esz + (vlenb - 1)) / vlenb;
-vext_set_elems_1s(vd, vta, (nf * max_elems) * esz,
-  registers_used * vlenb);
-}
+
+vext_set_tail_elems_1s(env, evl, vd, desc, nf, esz, max_elems);
  }
  
  /*

@@ -484,8 +482,6 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
  uint32_t vm = vext_vm(desc);
  uint32_t max_elems = vext_max_elems(desc, log2_esz);
  uint32_t esz = 1 << log2_esz;
-uint32_t total_elems = vext_get_total_elems(env, desc, esz);
-uint32_t vta = vext_vta(desc);
  uint32_t vma = vext_vma(desc);
  
  /*

Re: [PATCH 1/2] target/riscv/vector_helper.c: create vext_set_tail_elems_1s()

2023-02-26 Thread Philippe Mathieu-Daudé

On 26/2/23 18:05, Daniel Henrique Barboza wrote:

Commit 752614cab8e6 ("target/riscv: rvv: Add tail agnostic for vector
load / store instructions") added code to set the tail elements to 1 in
the end of vext_ldst_stride(), vext_ldst_us(), vext_ldst_index() and
vext_ldff(). Aside from a env->vl versus an evl value being used in the
first loop, the code is being repeated 4 times.

Create a helper to avoid code repetition in all those functions.
Arguments that are used in the callers (nf, esz and max_elems) are
passed as arguments. All other values are being derived inside the
helper.

Reviewed-by: Weiwei Li 
Reviewed-by: Frank Chang 
Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/vector_helper.c | 86 +---
  1 file changed, 30 insertions(+), 56 deletions(-)




+static void vext_set_tail_elems_1s(CPURISCVState *env, target_ulong vl,
+   void *vd, uint32_t desc, uint32_t nf,
+   uint32_t esz, uint32_t max_elems)
+{
+uint32_t total_elems = vext_get_total_elems(env, desc, esz);
+uint32_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
+uint32_t vta = vext_vta(desc);
+uint32_t registers_used;
+int k;
+
+for (k = 0; k < nf; ++k) {
+vext_set_elems_1s(vd, vta, (k * max_elems + vl) * esz,
+  (k * max_elems + max_elems) * esz);
+}
+
+if (nf * max_elems % total_elems != 0) {
+registers_used = ((nf * max_elems) * esz + (vlenb - 1)) / vlenb;
+vext_set_elems_1s(vd, vta, (nf * max_elems) * esz,
+  registers_used * vlenb);
+}


  for (unsigned k = 0; k < nf; ++k) {
  vext_set_elems_1s(vd, vta, (k * max_elems + vl) * esz,
(k * max_elems + max_elems) * esz);
  }

  if (nf * max_elems % total_elems != 0) {
  uint32_t cnt = (nf * max_elems) * esz;
  vext_set_elems_1s(vd, vta, cnt, QEMU_ALIGN_UP(cnt, vlenb));
  }

I suspect ROUND_UP() could be used if vlenb is a power of 2.



Re: [PATCH 2/2] target/riscv/vector_helper.c: avoid env_archcpu() when reading RISCVCPUConfig

2023-02-26 Thread Philippe Mathieu-Daudé

On 26/2/23 18:05, Daniel Henrique Barboza wrote:

This file has several uses of env_archcpu() that are used solely to read
cfg->vlen. Use the new riscv_cpu_cfg() inline instead.

Suggested-by: Weiwei Li 
Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/vector_helper.c | 20 ++--
  1 file changed, 10 insertions(+), 10 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PULL 00/13] testing updates (gitlab, cirrus, docker, avocado, windows)

2023-02-26 Thread Peter Maydell
On Fri, 24 Feb 2023 at 21:23, Philippe Mathieu-Daudé  wrote:
>
> On 24/2/23 20:52, Alex Bennée wrote:
> >
> > Peter Maydell  writes:
> >
> >> On Thu, 23 Feb 2023 at 15:57, Alex Bennée  wrote:
> >>>
> >>> The following changes since commit 
> >>> 79b677d658d3d35e1e776826ac4abb28cdce69b8:
> >>>
> >>>Merge tag 'net-pull-request' of https://github.com/jasowang/qemu
> >>> into staging (2023-02-21 11:28:31 +)
> >>>
> >>> are available in the Git repository at:
> >>>
> >>>https://gitlab.com/stsquad/qemu.git tags/pull-testing-next-230223-1
> >>>
> >>> for you to fetch changes up to e9969376f01180d7bcbee25ae8333983da7eda2c:
> >>>
> >>>cirrus.yml: Improve the windows_msys2_task (2023-02-23 15:48:23 +)
> >>>
> >>> 
> >>> testing updates:
> >>>
> >>>- ensure socat available for tests
> >>>- skip socat tests for MacOS
> >>>- properly clean up fifos after use
> >>>- make fp-test less chatty
> >>>- store test artefacts on Cirrus
> >>>- control custom runners with QEMU_CI knobs
> >>>- disable benchmark runs under tsan build
> >>>- update ubuntu 2004 to 2204
> >>>- skip nios2 kernel replay test
> >>>- add tuxrun baselines to avocado
> >>>- binary build of tricore tools
> >>>- export test results on cross builds
> >>>- improve windows builds
> >>>
> >>> 
> >>
> >> So I've been applying pullreqs relying on a combination of the
> >> private-runner CI jobs plus using the free minutes allowance
> >> on my personal gitlab account, and ad-hoc local builds. I'm
> >> a bit reluctant to do that for this one though, because it's
> >> touching all the gitlab config and we won't be able test that
> >> that is OK until we can do a full run with the standard config.
> >> What do you think ?
>
> What is the alternative, waiting 5 days up to March 1st?

That would be the other option, yes.

-- PMM



Re: [PATCH v2 00/10] Resolve isabus global

2023-02-26 Thread Bernhard Beschow



Am 24. Februar 2023 16:22:48 UTC schrieb "Michael S. Tsirkin" :
>On Thu, Jan 26, 2023 at 10:17:30PM +0100, Bernhard Beschow wrote:
>> This series resolves the global "isabus" variable and is basically a v2 of 
>> [1].
>> Note that the majority of the work consists of fixing ISA API calls in PIIX 
>> IDE
>> which implicitly rely on the usage of the isabus global.
>> 
>> Rather than adding an ISABus pointer in PCIIDEState as in [1] this series 
>> uses
>> a qemu_irq array which is roughly the approach outlined in [2]. Moreover, 
>> this
>> series considers backwards compatibility for user-created PIIX IDE
>> "Frankensten" devices by fishing out TYPE_ISA_BUS from the QOM tree inside
>> the PIIX IDE device model. This hack can be removed again once a deprecation
>> period of user-createable PIIX IDE devices is over. This deprecation wasn't
>> announced yet but now might be a good time.
>> 
>> This series is structured as follows: The first three patches massage the ISA
>> code for patch 8. Patches 4-8 change the PIIX IDE device models to not use 
>> the
>> isabus global implicitly. Finally, the last two patches clan up and remove 
>> the
>> isabus singleton.
>
>I expect there will be a v3 of this, right?

I would do it and I could rebase onto master if necessary. However, another 
series unrelated to this one but doing essentially the same thing with less 
backwards promises went through various iterations in the meantime. I don't 
know what the plan is.

Best regards,
Bernhard

>
>
>> Based-on: <20230109172347.1830-1-shen...@gmail.com>
>>   'Consolidate PIIX south bridges'
>> 
>> v2:
>> - Big rework sticking closer to [1], giving it more credit and reusing one 
>> patch
>> - Add io port cleanup
>> - Rebase onto [4] so changes to PIIX could be done once and centrally
>> 
>> Testing done:
>> * `make check`
>> * `./qemu-system-x86_64 -M x-remote -device piix3-ide` still fails 
>> gracefully with
>>   `qemu-system-x86_64: -device piix3-ide: No ISA bus found while piix3-ide 
>> requires one`
>> * `qemu-system-x86_64 -M pc -m 2G -cdrom 
>> manjaro-kde-21.3.2-220704-linux515.iso`
>> * `qemu-system-x86_64 -M q35 -m 2G -device piix4-ide -cdrom \
>>manjaro-kde-21.3.2-220704-linux515.iso`
>> * `qemu-system-mips64el -M malta -kernel vmlinux-3.2.0-4-5kc-malta -hda \
>>   debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=ttyS0"`
>> 
>> [1] https://patchew.org/QEMU/20210518215545.1793947-1-phi...@redhat.com/
>> [2] https://lists.nongnu.org/archive/html/qemu-devel/2020-03/msg01707.html
>> [3] https://people.debian.org/~aurel32/qemu/mips/
>> [4] https://patchew.org/QEMU/20230109172347.1830-1-shen...@gmail.com/
>> 
>> Bernhard Beschow (9):
>>   softmmu/ioport: Move portio_list_init() in front of portio_list_add()
>>   softmmu/ioport: Merge portio_list_add() into portio_list_init()
>>   softmmu/ioport: Remove unused functions
>>   hw/ide/piix: Disuse isa_get_irq()
>>   Revert "hw/ide: Fix crash when plugging a piix3-ide device into the
>> x-remote machine"
>>   hw/ide/pci: Add PCIIDEState::isa_irqs[]
>>   hw/ide/piix: Require an ISABus only for user-created instances
>>   hw/ide: Let ide_init_ioport() take a MemoryRegion argument instead of
>> ISADevice
>>   hw/isa/isa-bus: Resolve isabus global
>> 
>> Philippe Mathieu-Daudé (1):
>>   hw/isa: Remove use of global isa bus
>> 
>>  include/exec/ioport.h |  8 ++---
>>  include/hw/ide/internal.h |  3 +-
>>  include/hw/ide/pci.h  |  2 ++
>>  include/hw/isa/isa.h  | 15 
>>  hw/audio/adlib.c  |  4 +--
>>  hw/display/qxl.c  |  5 ++-
>>  hw/display/vga.c  |  8 ++---
>>  hw/dma/i82374.c   |  6 ++--
>>  hw/ide/ioport.c   | 19 +-
>>  hw/ide/isa.c  |  4 ++-
>>  hw/ide/piix.c | 75 +++
>>  hw/isa/isa-bus.c  | 54 +++-
>>  hw/isa/piix.c |  5 +++
>>  hw/watchdog/wdt_ib700.c   |  4 +--
>>  softmmu/ioport.c  | 70 +++-
>>  15 files changed, 149 insertions(+), 133 deletions(-)
>> 
>> -- 
>> 2.39.1
>> 
>



Re: [PATCH v2 06/10] hw/ide/pci: Add PCIIDEState::isa_irqs[]

2023-02-26 Thread Philippe Mathieu-Daudé

On 30/1/23 18:00, Bernhard Beschow wrote:



Am 26. Januar 2023 21:17:36 UTC schrieb Bernhard Beschow :

These legacy ISA IRQs allow the PIIX IDE functions to be wired up in
their south bridges and the VIA IDE functions to disuse
PCI_INTERRUPT_LINE as outlined in https://lists.nongnu.org/archive/html/
qemu-devel/2020-03/msg01707.html .



Suggested-by: Mark Cave-Ayland 


Signed-off-by: Bernhard Beschow 
---
include/hw/ide/pci.h | 1 +
1 file changed, 1 insertion(+)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH v6 0/5] dump: Make most of it target agnostic (build once)

2023-02-26 Thread Philippe Mathieu-Daudé

On 26/2/23 13:39, Marc-André Lureau wrote:


Philippe Mathieu-Daudé (5):
   dump: Replace tswapN() -> cpu_to_dumpN()
   dump: Replace TARGET_PAGE_SIZE -> qemu_target_page_size()
   dump: Clean included headers
   dump: Simplify compiling win_dump.o by introducing
     win_dump_available()
   dump: Add create_win_dump() stub for non-x86 targets


Reviewed-by: Marc-André Lureau >




Thanks, I'm going to queue this series with various qdev cleanups.



Re: [PATCH] hw/display/sm501: Implement more 2D raster operations

2023-02-26 Thread Philippe Mathieu-Daudé

On 16/2/23 15:40, BALATON Zoltan wrote:

Add simple implementation for two raster operations that are used by
AmigaOS which fixes graphics problems in some progtams using these.


Typo "programs".


Signed-off-by: BALATON Zoltan 
---
For definitions of these see:
https://learn.microsoft.com/en-us/windows/win32/gdi/ternary-raster-operations


Comment worth being in the commit description IMO.


  hw/display/sm501.c | 30 +-
  1 file changed, 29 insertions(+), 1 deletion(-)





[RFC PATCH v2 08/11] hw/arm/smmuv3: Add CMDs related to stage-2

2023-02-26 Thread Mostafa Saleh
CMD_TLBI_S2_IPA: As S1+S2 is not enabled, for now this can be the
same as CMD_TLBI_NH_VAA.

CMD_TLBI_S12_VMALL: Added new function to invalidate TLB by VMID.

For stage-1 only commands, add a check to to throw CERROR_ILL if used
when stage-1 is not supported.

Signed-off-by: Mostafa Saleh 
---
Changes in v2:
- Add checks for stage-1 only commands
- Rename smmuv3_s1_range_inval to smmuv3_range_inval
---
 hw/arm/smmu-common.c | 16 
 hw/arm/smmuv3.c  | 47 +++-
 hw/arm/trace-events  |  4 ++-
 include/hw/arm/smmu-common.h |  1 +
 4 files changed, 61 insertions(+), 7 deletions(-)

diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
index 3191a008c6..e4b477af10 100644
--- a/hw/arm/smmu-common.c
+++ b/hw/arm/smmu-common.c
@@ -135,6 +135,16 @@ static gboolean smmu_hash_remove_by_asid(gpointer key, 
gpointer value,
 
 return SMMU_IOTLB_ASID(*iotlb_key) == asid;
 }
+
+static gboolean smmu_hash_remove_by_vmid(gpointer key, gpointer value,
+ gpointer user_data)
+{
+uint16_t vmid = *(uint16_t *)user_data;
+SMMUIOTLBKey *iotlb_key = (SMMUIOTLBKey *)key;
+
+return SMMU_IOTLB_VMID(*iotlb_key) == vmid;
+}
+
 static gboolean smmu_hash_remove_by_asid_vmid_iova(gpointer key, gpointer 
value,
   gpointer user_data)
 {
@@ -187,6 +197,12 @@ void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid)
 g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_asid, &asid);
 }
 
+inline void smmu_iotlb_inv_vmid(SMMUState *s, uint16_t vmid)
+{
+trace_smmu_iotlb_inv_vmid(vmid);
+g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_vmid, &vmid);
+}
+
 /* VMSAv8-64 Translation */
 
 /**
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index f9c06723f9..8c76a48c8d 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -1034,7 +1034,7 @@ static void smmuv3_inv_notifiers_iova(SMMUState *s, int 
asid, dma_addr_t iova,
 }
 }
 
-static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
+static void smmuv3_range_inval(SMMUState *s, Cmd *cmd)
 {
 dma_addr_t end, addr = CMD_ADDR(cmd);
 uint8_t type = CMD_TYPE(cmd);
@@ -1059,7 +1059,7 @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
 }
 
 if (!tg) {
-trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, 1, ttl, leaf);
+trace_smmuv3_range_inval(vmid, asid, addr, tg, 1, ttl, leaf);
 smmuv3_inv_notifiers_iova(s, asid, addr, tg, 1);
 smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, 1, ttl);
 return;
@@ -1077,7 +1077,7 @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
 uint64_t mask = dma_aligned_pow2_mask(addr, end, 64);
 
 num_pages = (mask + 1) >> granule;
-trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, num_pages, ttl, 
leaf);
+trace_smmuv3_range_inval(vmid, asid, addr, tg, num_pages, ttl, leaf);
 smmuv3_inv_notifiers_iova(s, asid, addr, tg, num_pages);
 smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, num_pages, ttl);
 addr += mask + 1;
@@ -1211,12 +1211,22 @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
 {
 uint16_t asid = CMD_ASID(&cmd);
 
+if (!STAGE1_SUPPORTED(s)) {
+cmd_error = SMMU_CERROR_ILL;
+break;
+}
+
 trace_smmuv3_cmdq_tlbi_nh_asid(asid);
 smmu_inv_notifiers_all(&s->smmu_state);
 smmu_iotlb_inv_asid(bs, asid);
 break;
 }
 case SMMU_CMD_TLBI_NH_ALL:
+if (!STAGE1_SUPPORTED(s)) {
+cmd_error = SMMU_CERROR_ILL;
+break;
+}
+QEMU_FALLTHROUGH;
 case SMMU_CMD_TLBI_NSNH_ALL:
 trace_smmuv3_cmdq_tlbi_nh();
 smmu_inv_notifiers_all(&s->smmu_state);
@@ -1224,7 +1234,34 @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
 break;
 case SMMU_CMD_TLBI_NH_VAA:
 case SMMU_CMD_TLBI_NH_VA:
-smmuv3_s1_range_inval(bs, &cmd);
+if (!STAGE1_SUPPORTED(s)) {
+cmd_error = SMMU_CERROR_ILL;
+break;
+}
+smmuv3_range_inval(bs, &cmd);
+break;
+case SMMU_CMD_TLBI_S12_VMALL:
+uint16_t vmid = CMD_VMID(&cmd);
+
+if (!STAGE2_SUPPORTED(s)) {
+cmd_error = SMMU_CERROR_ILL;
+break;
+}
+
+trace_smmuv3_cmdq_tlbi_s12_vmid(vmid);
+smmu_inv_notifiers_all(&s->smmu_state);
+smmu_iotlb_inv_vmid(bs, vmid);
+break;
+case SMMU_CMD_TLBI_S2_IPA:
+if (!STAGE2_SUPPORTED(s)) {
+cmd_error = SMMU_CERROR_ILL;
+break;
+}
+/*
+ * As currently only either s1 or s2 are supported
+ * we can reuse same function for s2.
+ */
+smmuv3_range_inval(bs, &

[RFC PATCH v2 01/11] hw/arm/smmuv3: Add missing fields for IDR0

2023-02-26 Thread Mostafa Saleh
In preparation for adding stage-2 support.
Add IDR0 fields related to stage-2.

VMID16: 16-bit VMID supported.
S2P: Stage-2 translation supported.

They are described in 6.3.1 SMMU_IDR0.

No functional change intended.

Reviewed-by: Richard Henderson 
Reviewed-by: Eric Auger 
Signed-off-by: Mostafa Saleh 

---
Changes in V2:
- Collected Reviewed-by tags.
---
 hw/arm/smmuv3-internal.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
index e8f0ebf25e..183d5ac8dc 100644
--- a/hw/arm/smmuv3-internal.h
+++ b/hw/arm/smmuv3-internal.h
@@ -34,10 +34,12 @@ typedef enum SMMUTranslationStatus {
 /* MMIO Registers */
 
 REG32(IDR0,0x0)
+FIELD(IDR0, S2P, 0 , 1)
 FIELD(IDR0, S1P, 1 , 1)
 FIELD(IDR0, TTF, 2 , 2)
 FIELD(IDR0, COHACC,  4 , 1)
 FIELD(IDR0, ASID16,  12, 1)
+FIELD(IDR0, VMID16,  18, 1)
 FIELD(IDR0, TTENDIAN,21, 2)
 FIELD(IDR0, STALL_MODEL, 24, 2)
 FIELD(IDR0, TERM_MODEL,  26, 1)
-- 
2.39.2.637.g21b0678d19-goog




[RFC PATCH v2 07/11] hw/arm/smmuv3: Add VMID to tlb tagging

2023-02-26 Thread Mostafa Saleh
Allow TLB to be tagged with VMID.

If stage-1 is only supported, VMID is set to -1 and ignored from STE
and CMD_TLBI_NH* cmds.

Update smmu_iotlb_insert trace event to have vmid.

Signed-off-by: Mostafa Saleh 
---
Changes in v2:
-Fix TLB aliasing issue from missing check in smmu_iotlb_key_equal.
-Add vmid to traces smmu_iotlb_insert and smmu_iotlb_lookup_hit/miss.
-Add vmid to hash function.
---
 hw/arm/smmu-common.c | 36 ++--
 hw/arm/smmu-internal.h   |  2 ++
 hw/arm/smmuv3.c  | 12 +---
 hw/arm/trace-events  |  6 +++---
 include/hw/arm/smmu-common.h |  5 +++--
 5 files changed, 39 insertions(+), 22 deletions(-)

diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
index 3f448bc82e..3191a008c6 100644
--- a/hw/arm/smmu-common.c
+++ b/hw/arm/smmu-common.c
@@ -38,7 +38,7 @@ static guint smmu_iotlb_key_hash(gconstpointer v)
 
 /* Jenkins hash */
 a = b = c = JHASH_INITVAL + sizeof(*key);
-a += key->asid + key->level + key->tg;
+a += key->asid + key->vmid + key->level + key->tg;
 b += extract64(key->iova, 0, 32);
 c += extract64(key->iova, 32, 32);
 
@@ -53,13 +53,15 @@ static gboolean smmu_iotlb_key_equal(gconstpointer v1, 
gconstpointer v2)
 SMMUIOTLBKey *k1 = (SMMUIOTLBKey *)v1, *k2 = (SMMUIOTLBKey *)v2;
 
 return (k1->asid == k2->asid) && (k1->iova == k2->iova) &&
-   (k1->level == k2->level) && (k1->tg == k2->tg);
+   (k1->level == k2->level) && (k1->tg == k2->tg) &&
+   (k1->vmid == k2->vmid);
 }
 
-SMMUIOTLBKey smmu_get_iotlb_key(uint16_t asid, uint64_t iova,
+SMMUIOTLBKey smmu_get_iotlb_key(uint16_t asid, uint16_t vmid, uint64_t iova,
 uint8_t tg, uint8_t level)
 {
-SMMUIOTLBKey key = {.asid = asid, .iova = iova, .tg = tg, .level = level};
+SMMUIOTLBKey key = {.asid = asid, .vmid = vmid, .iova = iova,
+.tg = tg, .level = level};
 
 return key;
 }
@@ -78,7 +80,8 @@ SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg 
*cfg,
 uint64_t mask = subpage_size - 1;
 SMMUIOTLBKey key;
 
-key = smmu_get_iotlb_key(cfg->asid, iova & ~mask, tg, level);
+key = smmu_get_iotlb_key(cfg->asid, cfg->s2cfg.vmid,
+ iova & ~mask, tg, level);
 entry = g_hash_table_lookup(bs->iotlb, &key);
 if (entry) {
 break;
@@ -88,13 +91,13 @@ SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg 
*cfg,
 
 if (entry) {
 cfg->iotlb_hits++;
-trace_smmu_iotlb_lookup_hit(cfg->asid, iova,
+trace_smmu_iotlb_lookup_hit(cfg->asid, cfg->s2cfg.vmid, iova,
 cfg->iotlb_hits, cfg->iotlb_misses,
 100 * cfg->iotlb_hits /
 (cfg->iotlb_hits + cfg->iotlb_misses));
 } else {
 cfg->iotlb_misses++;
-trace_smmu_iotlb_lookup_miss(cfg->asid, iova,
+trace_smmu_iotlb_lookup_miss(cfg->asid, cfg->s2cfg.vmid, iova,
  cfg->iotlb_hits, cfg->iotlb_misses,
  100 * cfg->iotlb_hits /
  (cfg->iotlb_hits + cfg->iotlb_misses));
@@ -111,8 +114,10 @@ void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, 
SMMUTLBEntry *new)
 smmu_iotlb_inv_all(bs);
 }
 
-*key = smmu_get_iotlb_key(cfg->asid, new->entry.iova, tg, new->level);
-trace_smmu_iotlb_insert(cfg->asid, new->entry.iova, tg, new->level);
+*key = smmu_get_iotlb_key(cfg->asid, cfg->s2cfg.vmid, new->entry.iova,
+  tg, new->level);
+trace_smmu_iotlb_insert(cfg->asid, cfg->s2cfg.vmid, new->entry.iova,
+tg, new->level);
 g_hash_table_insert(bs->iotlb, key, new);
 }
 
@@ -130,8 +135,7 @@ static gboolean smmu_hash_remove_by_asid(gpointer key, 
gpointer value,
 
 return SMMU_IOTLB_ASID(*iotlb_key) == asid;
 }
-
-static gboolean smmu_hash_remove_by_asid_iova(gpointer key, gpointer value,
+static gboolean smmu_hash_remove_by_asid_vmid_iova(gpointer key, gpointer 
value,
   gpointer user_data)
 {
 SMMUTLBEntry *iter = (SMMUTLBEntry *)value;
@@ -142,18 +146,21 @@ static gboolean smmu_hash_remove_by_asid_iova(gpointer 
key, gpointer value,
 if (info->asid >= 0 && info->asid != SMMU_IOTLB_ASID(iotlb_key)) {
 return false;
 }
+if (info->vmid >= 0 && info->vmid != SMMU_IOTLB_VMID(iotlb_key)) {
+return false;
+}
 return ((info->iova & ~entry->addr_mask) == entry->iova) ||
((entry->iova & ~info->mask) == info->iova);
 }
 
-void smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
+void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova,
  uint8_t tg, uint64_t num_pages, uint8_t ttl)
 {
 /* if tg is not set we use 4KB range invalidation 

[RFC PATCH v2 10/11] hw/arm/smmuv3: Populate OAS based on CPU PARANGE

2023-02-26 Thread Mostafa Saleh
OAS used to be hardcoded to 44 bits, however according to SMMU manual
6.3.6 SMMU_IDR5, OAS must match the system physical address size, so
we read it from CPU PARANGE.

Remove PA_MAX and pa_range as they were not used.

Add SMMUv3State as an argument to decode_cd, so it can read the SMMU
OAS.

As CPU can use PARANGE with 52 bits, add 52 bits check to oas2bits,
and cap OAS to 48 bits for stage-1 and stage-2 if granule is not 64KB
as specified for SMMUv3.1 and later.

Signed-off-by: Mostafa Saleh 
---
 hw/arm/smmu-common.c | 13 +
 hw/arm/smmuv3-internal.h | 15 ++-
 hw/arm/smmuv3.c  | 41 ++--
 3 files changed, 46 insertions(+), 23 deletions(-)

diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
index e4b477af10..3a2b06fd7f 100644
--- a/hw/arm/smmu-common.c
+++ b/hw/arm/smmu-common.c
@@ -307,7 +307,7 @@ static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
 dma_addr_t baseaddr, indexmask;
 int stage = cfg->stage;
 SMMUTransTableInfo *tt = select_tt(cfg, iova);
-uint8_t level, granule_sz, inputsize, stride;
+uint8_t level, granule_sz, inputsize, stride, oas;
 
 if (!tt || tt->disabled) {
 info->type = SMMU_PTW_ERR_TRANSLATION;
@@ -319,7 +319,12 @@ static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
 inputsize = 64 - tt->tsz;
 level = 4 - (inputsize - 4) / stride;
 indexmask = SMMU_IDXMSK(inputsize, stride, level);
-baseaddr = extract64(tt->ttb, 0, 48);
+oas = cfg->oas;
+if (tt->granule_sz != 16) {
+oas = MIN(oas, 48);
+}
+
+baseaddr = extract64(tt->ttb, 0, oas);
 baseaddr &= ~indexmask;
 
 while (level < SMMU_LEVELS) {
@@ -416,8 +421,8 @@ static int smmu_ptw_64_s2(SMMUTransCfg *cfg,
  * Get the ttb from concatenated structure.
  * The offset is the idx * size of each ttb(number of ptes * (sizeof(pte))
  */
-uint64_t baseaddr = extract64(cfg->s2cfg.vttb, 0, 48) + (1 << stride) *
-  idx * sizeof(uint64_t);
+uint64_t baseaddr = extract64(cfg->s2cfg.vttb, 0, cfg->s2cfg.oas) +
+  (1 << stride) * idx * sizeof(uint64_t);
 dma_addr_t indexmask = SMMU_IDXMSK(inputsize, stride, level);
 
 baseaddr &= ~indexmask;
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
index 3388e1a5f8..25ae12fb5c 100644
--- a/hw/arm/smmuv3-internal.h
+++ b/hw/arm/smmuv3-internal.h
@@ -564,23 +564,12 @@ static inline int oas2bits(int oas_field)
 return 44;
 case 5:
 return 48;
+case 6:
+return 52;
 }
 return -1;
 }
 
-static inline int pa_range(STE *ste)
-{
-int oas_field = MIN(STE_S2PS(ste), SMMU_IDR5_OAS);
-
-if (!STE_S2AA64(ste)) {
-return 40;
-}
-
-return oas2bits(oas_field);
-}
-
-#define MAX_PA(ste) ((1 << pa_range(ste)) - 1)
-
 /* CD fields */
 
 #define CD_VALID(x)   extract32((x)->word[0], 31, 1)
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 7297f6adc1..bc4ec202f4 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -238,6 +238,13 @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo 
*info)
 
 static void smmuv3_init_regs(SMMUv3State *s)
 {
+/*
+ * According to 6.3.6 SMMU_IDR5, OAS must match the system physical address
+ * size.
+ */
+ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
+uint8_t oas = FIELD_EX64(armcpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
+
 /**
  * IDR0: stage1 only, AArch64 only, coherent access, 16b ASID,
  *   multi-level stream table
@@ -265,7 +272,7 @@ static void smmuv3_init_regs(SMMUv3State *s)
 s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN4K, 1);
 s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN16K, 1);
 s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1);
-s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS); /* 44 bits */
+s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, oas);
 
 s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
 s->cmdq.prod = 0;
@@ -374,6 +381,7 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
   STE *ste, SMMUEventInfo *event)
 {
 uint32_t config;
+uint8_t oas = FIELD_EX32(s->idr[5], IDR5, OAS);
 
 if (!STE_VALID(ste)) {
 if (!event->inval_ste_allowed) {
@@ -450,7 +458,16 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
 }
 
 
-cfg->s2cfg.oas = oas2bits(MIN(STE_S2PS(ste), SMMU_IDR5_OAS));
+cfg->s2cfg.oas = oas2bits(MIN(STE_S2PS(ste), oas));
+/*
+ * For SMMUv3.1 and later, when OAS == IAS == 52, the stage 2 input
+ * range is further limited to 48 bits unless STE.S2TG indicates a
+ * 64KB granule.
+ */
+if (cfg->s2cfg.granule_sz != 16) {
+cfg->s2cfg.oas = MIN(cfg->s2cfg.oas, 48);
+}
+
 /*
  * It is ILLEGAL for the address in S2TTB to be outside the range
  * described by the effective S2PS value.
@@ -607,10 +624,12 @@ static 

[RFC PATCH v2 06/11] hw/arm/smmuv3: Make TLB lookup work for stage-2

2023-02-26 Thread Mostafa Saleh
Right now, either stage-1 or stage-2 are supported, this simplifies
how we can deal with TLBs.
This patch makes TLB lookup work if stage-2 is enabled instead of
stage-1.
TLB lookup is done before a PTW, if a valid entry is found we won't
do the PTW.
To be able to do TLB lookup, we need the correct tagging info, as
granularity and input size, so we get this based on the supported
translation stage. The TLB entries are added correctly from each
stage PTW.

When nested translation is supported, this would need to change, for
example if we go with a combined TLB implementation, we would need to
use the min of the granularities in TLB.

As stage-2 shouldn't be tagged by ASID, it will be set to -1 if S1P
is not enabled.

Signed-off-by: Mostafa Saleh 
---
Changes in v2:
- check if S1 is enabled(not supported) when reading S1 TT.
---
 hw/arm/smmuv3.c | 45 ++---
 1 file changed, 34 insertions(+), 11 deletions(-)

diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index dc74a5442d..ce193e9598 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -697,6 +697,9 @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, 
SMMUTransCfg *cfg,
 STE ste;
 CD cd;
 
+/* ASID defaults to -1 (if s1 is not supported). */
+cfg->asid = -1;
+
 ret = smmu_find_ste(s, sid, &ste, event);
 if (ret) {
 return ret;
@@ -787,6 +790,7 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion 
*mr, hwaddr addr,
 SMMUTLBEntry *cached_entry = NULL;
 SMMUTransTableInfo *tt;
 SMMUTransCfg *cfg = NULL;
+uint8_t granule_sz, tsz;
 IOMMUTLBEntry entry = {
 .target_as = &address_space_memory,
 .iova = addr,
@@ -822,21 +826,40 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion 
*mr, hwaddr addr,
 goto epilogue;
 }
 
-tt = select_tt(cfg, addr);
-if (!tt) {
-if (cfg->record_faults) {
-event.type = SMMU_EVT_F_TRANSLATION;
-event.u.f_translation.addr = addr;
-event.u.f_translation.rnw = flag & 0x1;
+if (cfg->stage == 1) {
+/* Select stage1 translation table. */
+tt = select_tt(cfg, addr);
+if (!tt) {
+if (cfg->record_faults) {
+event.type = SMMU_EVT_F_TRANSLATION;
+event.u.f_translation.addr = addr;
+event.u.f_translation.rnw = flag & 0x1;
+}
+status = SMMU_TRANS_ERROR;
+goto epilogue;
 }
-status = SMMU_TRANS_ERROR;
-goto epilogue;
-}
+granule_sz = tt->granule_sz;
+tsz = tt->tsz;
 
-page_mask = (1ULL << (tt->granule_sz)) - 1;
+} else {
+/* Stage2. */
+granule_sz = cfg->s2cfg.granule_sz;
+tsz = cfg->s2cfg.tsz;
+}
+/*
+ * TLB lookup looks for granule and input size for a translation stage,
+ * as only one stage is supported right now, choose the right values
+ * from the configuration.
+ */
+page_mask = (1ULL << granule_sz) - 1;
 aligned_addr = addr & ~page_mask;
 
-cached_entry = smmu_iotlb_lookup(bs, cfg, tt, aligned_addr);
+SMMUTransTableInfo temp = {
+.granule_sz = granule_sz,
+.tsz = tsz,
+};
+
+cached_entry = smmu_iotlb_lookup(bs, cfg, &temp, aligned_addr);
 if (cached_entry) {
 if ((flag & IOMMU_WO) && !(cached_entry->entry.perm & IOMMU_WO)) {
 status = SMMU_TRANS_ERROR;
-- 
2.39.2.637.g21b0678d19-goog




[RFC PATCH v2 03/11] hw/arm/smmuv3: Refactor stage-1 PTW

2023-02-26 Thread Mostafa Saleh
In preparation for adding stage-2 support, rename smmu_ptw_64 to
smmu_ptw_64_s1 and refactor some of the code so it can be reused in
stage-2 page table walk.

Remove AA64 check from PTW as decode_cd already ensures that AA64 is
used, otherwise it faults with C_BAD_CD.

A stage member is added to SMMUPTWEventInfo to differentiate
between stage-1 and stage-2 ptw faults.

Add stage argument to trace_smmu_ptw_level be consistent with other
trace events.

Signed-off-by: Mostafa Saleh 
---
Changes in v2:
- Refactor common functions to be use in stage-2.
- Add stage to SMMUPTWEventInfo.
- Remove AA64 check.
---
 hw/arm/smmu-common.c | 27 ++-
 hw/arm/smmuv3.c  |  2 ++
 hw/arm/trace-events  |  2 +-
 include/hw/arm/smmu-common.h | 15 ---
 4 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
index 0a5a60ca1e..b49c1affdb 100644
--- a/hw/arm/smmu-common.c
+++ b/hw/arm/smmu-common.c
@@ -264,7 +264,7 @@ SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t 
iova)
 }
 
 /**
- * smmu_ptw_64 - VMSAv8-64 Walk of the page tables for a given IOVA
+ * smmu_ptw_64_s1 - VMSAv8-64 Walk of the page tables for a given IOVA
  * @cfg: translation config
  * @iova: iova to translate
  * @perm: access type
@@ -276,9 +276,9 @@ SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t 
iova)
  * Upon success, @tlbe is filled with translated_addr and entry
  * permission rights.
  */
-static int smmu_ptw_64(SMMUTransCfg *cfg,
-   dma_addr_t iova, IOMMUAccessFlags perm,
-   SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
+static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
+  dma_addr_t iova, IOMMUAccessFlags perm,
+  SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
 {
 dma_addr_t baseaddr, indexmask;
 int stage = cfg->stage;
@@ -291,14 +291,14 @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
 }
 
 granule_sz = tt->granule_sz;
-stride = granule_sz - 3;
+stride = SMMU_STRIDE(granule_sz);
 inputsize = 64 - tt->tsz;
 level = 4 - (inputsize - 4) / stride;
-indexmask = (1ULL << (inputsize - (stride * (4 - level - 1;
+indexmask = SMMU_IDXMSK(inputsize, stride, level);
 baseaddr = extract64(tt->ttb, 0, 48);
 baseaddr &= ~indexmask;
 
-while (level <= 3) {
+while (level < SMMU_LEVELS) {
 uint64_t subpage_size = 1ULL << level_shift(level, granule_sz);
 uint64_t mask = subpage_size - 1;
 uint32_t offset = iova_level_offset(iova, inputsize, level, 
granule_sz);
@@ -309,7 +309,7 @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
 if (get_pte(baseaddr, offset, &pte, info)) {
 goto error;
 }
-trace_smmu_ptw_level(level, iova, subpage_size,
+trace_smmu_ptw_level(stage, level, iova, subpage_size,
  baseaddr, offset, pte);
 
 if (is_invalid_pte(pte) || is_reserved_pte(pte, level)) {
@@ -358,6 +358,7 @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
 info->type = SMMU_PTW_ERR_TRANSLATION;
 
 error:
+info->stage = 1;
 tlbe->entry.perm = IOMMU_NONE;
 return -EINVAL;
 }
@@ -376,15 +377,7 @@ error:
 int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
  SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
 {
-if (!cfg->aa64) {
-/*
- * This code path is not entered as we check this while decoding
- * the configuration data in the derived SMMU model.
- */
-g_assert_not_reached();
-}
-
-return smmu_ptw_64(cfg, iova, perm, tlbe, info);
+return smmu_ptw_64_s1(cfg, iova, perm, tlbe, info);
 }
 
 /**
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 270c80b665..4e90343996 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -716,6 +716,8 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion 
*mr, hwaddr addr,
 cached_entry = g_new0(SMMUTLBEntry, 1);
 
 if (smmu_ptw(cfg, aligned_addr, flag, cached_entry, &ptw_info)) {
+/* All faults from PTW has S2 field. */
+event.u.f_walk_eabt.s2 = (ptw_info.stage == 2);
 g_free(cached_entry);
 switch (ptw_info.type) {
 case SMMU_PTW_ERR_WALK_EABT:
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
index 2dee296c8f..205ac04573 100644
--- a/hw/arm/trace-events
+++ b/hw/arm/trace-events
@@ -5,7 +5,7 @@ virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
 
 # smmu-common.c
 smmu_add_mr(const char *name) "%s"
-smmu_ptw_level(int level, uint64_t iova, size_t subpage_size, uint64_t 
baseaddr, uint32_t offset, uint64_t pte) "level=%d iova=0x%"PRIx64" 
subpage_sz=0x%zx baseaddr=0x%"PRIx64" offset=%d => pte=0x%"PRIx64
+smmu_ptw_level(int stage, int level, uint64_t iova, size_t subpage_size, 
uint64_t baseaddr, uint32_t offset, uint64_t pte) "stage=%d level=%d 
iova=0x%"PRIx64" subpage_sz=0x%zx baseaddr=0x%"PRIx64" offset=%d => 
pte=

[RFC PATCH v2 00/11] Add stage-2 translation for SMMUv3

2023-02-26 Thread Mostafa Saleh
This patch series adds stage-2 translation support for SMMUv3. It is
controlled by a new system property “arm-smmuv3.stage”.
- When set to “1”: Stage-1 only would be advertised and supported (default
behaviour)
- When set to “2”: Stage-2 only would be advertised and supported.
- Value “all” is reserved for nesting support. However it is not
implemented in this patch series (more about this in the end)

Features implemented in stage-2 are mostly synonymous with stage-1
- VMID16.
- Only AArch64 translation tables are supported.
- Stall is not supported.
- HTTU is not supported, SW is expected to maintain the Access flag.

To make it easy to support nesting, a new structure(SMMUS2Cfg) is
embedded within SMMUTransCfg, to hold stage-2 configuration.

TLBs were updated to support VMID, where when stage-2 is used ASID are
set to -1 and ignored and when stage-1 is used VMID is set to -1 and
ignored.
As only one stage is supported at a time at the moment, TLB will
represent IPA=>PA translation with proper attributes(granularity and
t0sz) parsed from STEs for stage-2, and will represent VA=>PA
translation with proper attributes parsed from the CDs for stage-1.

New commands where added that are used with stage-2
- CMD_TLBI_S12_VMALL: Invalidate all translations for a VMID.
- CMD_TLBI_S2_IPA: Invalidate stage-2 by VMID and IPA

These patches update OAS, as it used to be hardcoded to 44 bits, and
according to user manual ”6.3.6 SMMU_IDR5”, OAS must match the
system physical address size, so OAS is updated to be read from CPU
PARANGE.

This patch series can be used to run Linux pKVM SMMUv3 patches (currently on 
the list)
which controls stage-2 (from EL2) while providing a paravirtualized
interface the host(EL1)
https://lore.kernel.org/kvmarm/20230201125328.2186498-1-jean-phili...@linaro.org/

Looking forward, nesting is the next feature to go for, here are some
thoughts about this:

- TLB would require big changes for this, we can go either for a combined
implementation or per stage one. This would affect returns from PTW and
invalidation commands.

- Stage-1 data structures should be translated by stage-2 if enabled (as
context descriptors and ttb0/ttb1)

- Translated addresses from stage-1 should be translated by stage-2 if
enabled.

- Record faults should be separated between stage-1 (CD_R) and stage-2
(S2R).

- Some existing commands(as CMD_TLBI_S2_IPA, CMD_TLBI_NH_ASID …) would be
modified and some of those would be based on the design of the TLBs.

- Currently, VMID is ignored when stage-1 is used as it can’t be used with
stage-2. However when nesting is advertised VMID shouldn’t be ignored
even if stage-2 is bypassed.

Changes in v2:
-Collected Reviewed-by tags
-Add oas to SMMUS2Cfg, and use it in PTW
-Add stage member to to SMMUPTWEventInfo to differentiate stage-1 and
 stage-2 PTW faults
-Move stage-2 knob to the last patch
-Add all STE parsing in one patch
-Pares and use S2PS and S2ENDI
-Split S2AFF patch over PTW and STE patches.
-Fix TLB aliasing issue
-Renaming and refactoring and rewording commits.
-Populate OAS based on PARANGE
-Add checks for stage-1 only commands
-Update trace events to hold translation stage, vmid when possible
-Remove feature flags for supported stages as they were redundant with IDR0


Mostafa Saleh (11):
  hw/arm/smmuv3: Add missing fields for IDR0
  hw/arm/smmuv3: Update translation config to hold stage-2
  hw/arm/smmuv3: Refactor stage-1 PTW
  hw/arm/smmuv3: Add page table walk for stage-2
  hw/arm/smmuv3: Parse STE config for stage-2
  hw/arm/smmuv3: Make TLB lookup work for stage-2
  hw/arm/smmuv3: Add VMID to tlb tagging
  hw/arm/smmuv3: Add CMDs related to stage-2
  hw/arm/smmuv3: Add stage-2 support in iova notifier
  hw/arm/smmuv3: Populate OAS based on CPU PARANGE
  hw/arm/smmuv3: Add knob to choose translation stage and enable stage-2

 hw/arm/smmu-common.c | 212 ++---
 hw/arm/smmu-internal.h   |  41 
 hw/arm/smmuv3-internal.h |  21 +--
 hw/arm/smmuv3.c  | 352 ++-
 hw/arm/trace-events  |  14 +-
 include/hw/arm/smmu-common.h |  32 +++-
 include/hw/arm/smmuv3.h  |   4 +
 7 files changed, 577 insertions(+), 99 deletions(-)

-- 
2.39.2.637.g21b0678d19-goog




[RFC PATCH v2 11/11] hw/arm/smmuv3: Add knob to choose translation stage and enable stage-2

2023-02-26 Thread Mostafa Saleh
As everything is in place, we can use a new system property to
advertise which stage is supported and remove bad_ste from STE
stage2 config.

The property added arm-smmuv3.stage can have 3 values:
- "1": Stage-1 only is advertised.
- "2": Stage-2 only is advertised.
- "all": Stage-1 + Stage-2 are supported, which is not implemented in
this patch series.

If not passed or an unsupported value is passed, it will default to
stage-1.

Advertise VMID16.

Don't try to decode CD, if stage-2 is configured.

Signed-off-by: Mostafa Saleh 
---
Changes in v2:
- Squash knob patch with stage-2 enable patch.
- Don't try to decode CD, if stage-2 is configured.
---
 hw/arm/smmuv3.c | 34 +-
 include/hw/arm/smmuv3.h |  1 +
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index bc4ec202f4..ebffc7e5f5 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -21,6 +21,7 @@
 #include "hw/irq.h"
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
 #include "hw/qdev-core.h"
 #include "hw/pci/pci.h"
 #include "cpu.h"
@@ -245,14 +246,20 @@ static void smmuv3_init_regs(SMMUv3State *s)
 ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
 uint8_t oas = FIELD_EX64(armcpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
 
-/**
- * IDR0: stage1 only, AArch64 only, coherent access, 16b ASID,
- *   multi-level stream table
+/*
+ * Based on sys property, the stages supported in smmu will be advertised.
+ * At the moment "all" is not supported and default to stage-1.
  */
-s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S1P, 1); /* stage 1 supported */
+if (s->stage && !strcmp("2", s->stage)) {
+s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S2P, 1);
+} else {
+s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S1P, 1);
+}
+
 s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTF, 2); /* AArch64 PTW only */
 s->idr[0] = FIELD_DP32(s->idr[0], IDR0, COHACC, 1); /* IO coherent */
 s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ASID16, 1); /* 16-bit ASID */
+s->idr[0] = FIELD_DP32(s->idr[0], IDR0, VMID16, 1); /* 16-bit VMID */
 s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTENDIAN, 2); /* little endian */
 s->idr[0] = FIELD_DP32(s->idr[0], IDR0, STALL_MODEL, 1); /* No stall */
 /* terminated transaction will always be aborted/error returned */
@@ -508,10 +515,6 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
 qemu_log_mask(LOG_UNIMP, "SMMUv3 Stall not implemented!\n");
 goto bad_ste;
 }
-
-/* This is still here as stage 2 has not been fully enabled yet. */
-qemu_log_mask(LOG_UNIMP, "SMMUv3 does not support stage 2 yet\n");
-goto bad_ste;
 }
 
 if (STE_S1CDMAX(ste) != 0) {
@@ -739,7 +742,7 @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, 
SMMUTransCfg *cfg,
 return ret;
 }
 
-if (cfg->aborted || cfg->bypassed) {
+if (cfg->aborted || cfg->bypassed || (cfg->stage == 2)) {
 return 0;
 }
 
@@ -1801,6 +1804,18 @@ static const VMStateDescription vmstate_smmuv3 = {
 }
 };
 
+static Property smmuv3_properties[] = {
+/*
+ * Stages of translation advertised.
+ * "1": Stage 1
+ * "2": Stage 2
+ * "all": Stage 1 + Stage 2
+ * Defaults to stage 1
+ */
+DEFINE_PROP_STRING("stage", SMMUv3State, stage),
+DEFINE_PROP_END_OF_LIST()
+};
+
 static void smmuv3_instance_init(Object *obj)
 {
 /* Nothing much to do here as of now */
@@ -1817,6 +1832,7 @@ static void smmuv3_class_init(ObjectClass *klass, void 
*data)
&c->parent_phases);
 c->parent_realize = dc->realize;
 dc->realize = smmu_realize;
+device_class_set_props(dc, smmuv3_properties);
 }
 
 static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
index 6031d7d325..d183a62766 100644
--- a/include/hw/arm/smmuv3.h
+++ b/include/hw/arm/smmuv3.h
@@ -62,6 +62,7 @@ struct SMMUv3State {
 
 qemu_irq irq[4];
 QemuMutex mutex;
+char *stage;
 };
 
 typedef enum {
-- 
2.39.2.637.g21b0678d19-goog




[RFC PATCH v2 09/11] hw/arm/smmuv3: Add stage-2 support in iova notifier

2023-02-26 Thread Mostafa Saleh
In smmuv3_notify_iova, read the granule based on translation stage
and use VMID if valid value is sent.

Signed-off-by: Mostafa Saleh 
---
 hw/arm/smmuv3.c | 39 ++-
 hw/arm/trace-events |  2 +-
 2 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 8c76a48c8d..7297f6adc1 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -971,18 +971,21 @@ epilogue:
  * @mr: IOMMU mr region handle
  * @n: notifier to be called
  * @asid: address space ID or negative value if we don't care
+ * @vmid: virtual machine ID or negative value if we don't care
  * @iova: iova
  * @tg: translation granule (if communicated through range invalidation)
  * @num_pages: number of @granule sized pages (if tg != 0), otherwise 1
  */
 static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
IOMMUNotifier *n,
-   int asid, dma_addr_t iova,
-   uint8_t tg, uint64_t num_pages)
+   int asid, int vmid,
+   dma_addr_t iova, uint8_t tg,
+   uint64_t num_pages)
 {
 SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
 IOMMUTLBEvent event;
 uint8_t granule;
+SMMUv3State *s = sdev->smmu;
 
 if (!tg) {
 SMMUEventInfo event = {.inval_ste_allowed = true};
@@ -997,11 +1000,20 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
 return;
 }
 
-tt = select_tt(cfg, iova);
-if (!tt) {
+if (vmid >= 0 && cfg->s2cfg.vmid != vmid) {
 return;
 }
-granule = tt->granule_sz;
+
+if (STAGE1_SUPPORTED(s)) {
+tt = select_tt(cfg, iova);
+if (!tt) {
+return;
+}
+granule = tt->granule_sz;
+} else {
+granule = cfg->s2cfg.granule_sz;
+}
+
 } else {
 granule = tg * 2 + 10;
 }
@@ -1015,9 +1027,10 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
 memory_region_notify_iommu_one(n, &event);
 }
 
-/* invalidate an asid/iova range tuple in all mr's */
-static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova,
-  uint8_t tg, uint64_t num_pages)
+/* invalidate an asid/vmid/iova range tuple in all mr's */
+static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, int vmid,
+  dma_addr_t iova, uint8_t tg,
+  uint64_t num_pages)
 {
 SMMUDevice *sdev;
 
@@ -1025,11 +1038,11 @@ static void smmuv3_inv_notifiers_iova(SMMUState *s, int 
asid, dma_addr_t iova,
 IOMMUMemoryRegion *mr = &sdev->iommu;
 IOMMUNotifier *n;
 
-trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, iova,
-tg, num_pages);
+trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, vmid,
+iova, tg, num_pages);
 
 IOMMU_NOTIFIER_FOREACH(n, mr) {
-smmuv3_notify_iova(mr, n, asid, iova, tg, num_pages);
+smmuv3_notify_iova(mr, n, asid, vmid, iova, tg, num_pages);
 }
 }
 }
@@ -1060,7 +1073,7 @@ static void smmuv3_range_inval(SMMUState *s, Cmd *cmd)
 
 if (!tg) {
 trace_smmuv3_range_inval(vmid, asid, addr, tg, 1, ttl, leaf);
-smmuv3_inv_notifiers_iova(s, asid, addr, tg, 1);
+smmuv3_inv_notifiers_iova(s, asid, vmid, addr, tg, 1);
 smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, 1, ttl);
 return;
 }
@@ -1078,7 +1091,7 @@ static void smmuv3_range_inval(SMMUState *s, Cmd *cmd)
 
 num_pages = (mask + 1) >> granule;
 trace_smmuv3_range_inval(vmid, asid, addr, tg, num_pages, ttl, leaf);
-smmuv3_inv_notifiers_iova(s, asid, addr, tg, num_pages);
+smmuv3_inv_notifiers_iova(s, asid, vmid, addr, tg, num_pages);
 smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, num_pages, ttl);
 addr += mask + 1;
 }
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
index f8fdf1ca9f..cdc1ea06a8 100644
--- a/hw/arm/trace-events
+++ b/hw/arm/trace-events
@@ -53,5 +53,5 @@ smmuv3_cmdq_tlbi_s12_vmid(uint16_t vmid) "vmid=%d"
 smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
 smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu 
mr=%s"
 smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu 
mr=%s"
-smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint64_t iova, 
uint8_t tg, uint64_t num_pages) "iommu mr=%s asid=%d iova=0x%"PRIx64" tg=%d 
num_pages=0x%"PRIx64
+smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint16_t vmid, 
uint64_t iova, uint8_t tg, uint64_t num_pages) "iommu mr=%s asid=%d vmid=%d 
iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64
 
-- 
2.39.2.637.g21b0678d19-goog




[RFC PATCH v2 05/11] hw/arm/smmuv3: Parse STE config for stage-2

2023-02-26 Thread Mostafa Saleh
Parse stage-2 configuration from STE and populate it in SMMUS2Cfg.
Validity of these value are checked when possible.

Only AA64 tables are supported and STT is not supported.

According to SMMUv3 user manual "5.2 Stream Table Entry": All fields
with an S2 prefix (with the exception of S2VMID) are IGNORED when
stage-2 bypasses translation (Config[1] == 0).

Which means that VMID can be used(for TLB tagging) even if stage-2 is
bypassed, so we parse it unconditionally when S2P exists. Otherwise
it is set to -1.(only S1P)

As stall is not supported, if S2S is set the translation would abort.
For S2R, we reuse the same code used for stage-1 with flag
record_faults. However when nested translation is supported we would
need to separate stage-1 and stage-2 faults.

Signed-off-by: Mostafa Saleh 
---
Changes in V2:
- Parse S2PS and S2ENDI
- Squash with S2VMID parsing patch
- Squash with S2AFF parsing
- Squash with fault reporting patch
- Add check for S2T0SZ
- Renaming and refactoring code
---
 hw/arm/smmuv3-internal.h |   4 ++
 hw/arm/smmuv3.c  | 138 +++
 include/hw/arm/smmuv3.h  |   3 +
 3 files changed, 145 insertions(+)

diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
index 183d5ac8dc..3388e1a5f8 100644
--- a/hw/arm/smmuv3-internal.h
+++ b/hw/arm/smmuv3-internal.h
@@ -526,9 +526,13 @@ typedef struct CD {
 #define STE_S2TG(x)extract32((x)->word[5], 14, 2)
 #define STE_S2PS(x)extract32((x)->word[5], 16, 3)
 #define STE_S2AA64(x)  extract32((x)->word[5], 19, 1)
+#define STE_S2ENDI(x)  extract32((x)->word[5], 20, 1)
+#define STE_S2AFFD(x)  extract32((x)->word[5], 21, 1)
 #define STE_S2HD(x)extract32((x)->word[5], 24, 1)
 #define STE_S2HA(x)extract32((x)->word[5], 25, 1)
 #define STE_S2S(x) extract32((x)->word[5], 26, 1)
+#define STE_S2R(x) extract32((x)->word[5], 27, 1)
+
 #define STE_CTXPTR(x)   \
 ({  \
 unsigned long addr; \
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 4e90343996..dc74a5442d 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -329,6 +329,46 @@ static int smmu_get_cd(SMMUv3State *s, STE *ste, uint32_t 
ssid,
 return 0;
 }
 
+/*
+ * Max valid value is 39 when SMMU_IDR3.STT == 0.
+ * In architectures after SMMUv3.0:
+ * - If STE.S2TG selects a 4KB or 16KB granule, the minimum valid value for 
this
+ * field is MAX(16, 64-IAS)
+ * - If STE.S2TG selects a 64KB granule, the minimum valid value for this field
+ * is (64-IAS).
+ * As we only support AA64, IAS = OAS.
+ */
+static bool t0sz_valid(SMMUTransCfg *cfg)
+{
+if (cfg->s2cfg.tsz > 39) {
+return false;
+}
+
+if (cfg->s2cfg.granule_sz == 16) {
+return (cfg->s2cfg.tsz >= 64 - cfg->s2cfg.oas);
+}
+
+return (cfg->s2cfg.tsz >= MAX(64 - cfg->s2cfg.oas, 16));
+}
+
+/*
+ * Return true if s2 page table config is valid.
+ * This checks with the configured start level, ias_bits and granularity we can
+ * have a valid page table as described in ARM ARM D8.2 Translation process.
+ * The idea here is to see for the highest possible number of IPA bits, how
+ * many concatenated tables we would need, if it is more than 16, then this is
+ * not possible.
+ */
+static bool s2_pgtable_config_valid(uint8_t sl0, uint8_t t0sz, uint8_t gran)
+{
+int level = get_start_level(sl0, gran);
+uint64_t ipa_bits = 64 - t0sz;
+uint64_t max_ipa = (1ULL << ipa_bits) - 1;
+int nr_concat = pgd_idx(level, gran, max_ipa) + 1;
+
+return nr_concat <= SMMU_MAX_S2_CONCAT;
+}
+
 /* Returns < 0 in case of invalid STE, 0 otherwise */
 static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
   STE *ste, SMMUEventInfo *event)
@@ -354,7 +394,105 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
 return 0;
 }
 
+/*
+ * If a stage is enabled in SW while not advertised, throw bad ste
+ * according to SMMU manual 5.2 Stream Table Entry - [3:1] Config.
+ */
+if (!STAGE1_SUPPORTED(s) && STE_CFG_S1_ENABLED(config)) {
+qemu_log_mask(LOG_GUEST_ERROR, "SMMUv3 S1 used but not supported.\n");
+goto bad_ste;
+}
+if (!STAGE2_SUPPORTED(s) && STE_CFG_S2_ENABLED(config)) {
+qemu_log_mask(LOG_GUEST_ERROR, "SMMUv3 S2 used but not supported.\n");
+goto bad_ste;
+}
+
+if (STAGE2_SUPPORTED(s)) {
+/* VMID is considered even if s2 is disabled. */
+cfg->s2cfg.vmid = STE_S2VMID(ste);
+} else {
+/* Default to -1 */
+cfg->s2cfg.vmid = -1;
+}
+
 if (STE_CFG_S2_ENABLED(config)) {
+cfg->stage = 2;
+
+if (STE_S2AA64(ste) == 0x0) {
+qemu_log_mask(LOG_UNIMP,
+  "SMMUv3 AArch32 tables not supported\n");
+g_assert_not_reached();
+}
+
+switch (STE_S2TG(ste)) {
+ca

[RFC PATCH v2 02/11] hw/arm/smmuv3: Update translation config to hold stage-2

2023-02-26 Thread Mostafa Saleh
In preparation for adding stage-2 support, add a S2 config
struct(SMMUS2Cfg), composed of the following fields and embedded in
the main SMMUTransCfg:
 -tsz: Input range
 -sl0: start level of translation
 -affd: AF fault disable
 -granule_sz: Granule page shift
 -vmid: VMID
 -vttb: PA of translation table
 -oas: Output address size

They will be used in the next patches in stage-2 address translation.

No functional change intended.

Signed-off-by: Mostafa Saleh 
---
Changes in v2:
-Add oas
---
 include/hw/arm/smmu-common.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
index 9fcff26357..2deead08d6 100644
--- a/include/hw/arm/smmu-common.h
+++ b/include/hw/arm/smmu-common.h
@@ -58,6 +58,16 @@ typedef struct SMMUTLBEntry {
 uint8_t granule;
 } SMMUTLBEntry;
 
+typedef struct SMMUS2Cfg {
+uint8_t tsz;/* Input range */
+uint8_t sl0;/* Start level of translation */
+bool affd;  /* AF Fault Disable */
+uint8_t granule_sz; /* Granule page shift */
+uint8_t oas;/* Output address size */
+uint16_t vmid;  /* Virtual machine ID */
+uint64_t vttb;  /* PA of translation table */
+} SMMUS2Cfg;
+
 /*
  * Generic structure populated by derived SMMU devices
  * after decoding the configuration information and used as
@@ -77,6 +87,7 @@ typedef struct SMMUTransCfg {
 SMMUTransTableInfo tt[2];
 uint32_t iotlb_hits;   /* counts IOTLB hits for this asid */
 uint32_t iotlb_misses; /* counts IOTLB misses for this asid */
+struct SMMUS2Cfg s2cfg;
 } SMMUTransCfg;
 
 typedef struct SMMUDevice {
-- 
2.39.2.637.g21b0678d19-goog




[RFC PATCH v2 04/11] hw/arm/smmuv3: Add page table walk for stage-2

2023-02-26 Thread Mostafa Saleh
In preparation for adding stage-2 support, add Stage-2 PTW code.
Only Aarch64 format is supported as stage-1.

Nesting stage-1 and stage-2 is not supported right now.

HTTU is not supported, SW is expected to maintain the Access flag.
This is described in the SMMUv3 manual "5.2. Stream Table Entry" in
"[181] S2AFFD".
This flag determines the behavior on access of a stage-2 page whose
descriptor has AF == 0:
- 0b0: An Access flag fault occurs (stall not supported).
- 0b1: An Access flag fault never occurs.
An Access fault takes priority over a Permission fault.

Checks for IPA and output PA are done according to the user manual
"3.4 Address sizes".

Signed-off-by: Mostafa Saleh 
---
Changes in v2:
- Squash S2AFF PTW code.
- Use common functions between stage-1 and stage-2.
- Add checks for IPA and out PA.
---
 hw/arm/smmu-common.c   | 132 -
 hw/arm/smmu-internal.h |  39 
 2 files changed, 170 insertions(+), 1 deletion(-)

diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
index b49c1affdb..3f448bc82e 100644
--- a/hw/arm/smmu-common.c
+++ b/hw/arm/smmu-common.c
@@ -363,6 +363,130 @@ error:
 return -EINVAL;
 }
 
+/**
+ * smmu_ptw_64_s2 - VMSAv8-64 Walk of the page tables for a given IOVA
+ * for stage-2.
+ * @cfg: translation config
+ * @iova: iova to translate
+ * @perm: access type
+ * @tlbe: SMMUTLBEntry (out)
+ * @info: handle to an error info
+ *
+ * Return 0 on success, < 0 on error. In case of error, @info is filled
+ * and tlbe->perm is set to IOMMU_NONE.
+ * Upon success, @tlbe is filled with translated_addr and entry
+ * permission rights.
+ */
+static int smmu_ptw_64_s2(SMMUTransCfg *cfg,
+  dma_addr_t iova, IOMMUAccessFlags perm,
+  SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
+{
+const int stage = 2;
+int granule_sz = cfg->s2cfg.granule_sz;
+/* ARM ARM: Table D8-7. */
+int inputsize = 64 - cfg->s2cfg.tsz;
+int level = get_start_level(cfg->s2cfg.sl0, granule_sz);
+int stride = SMMU_STRIDE(granule_sz);
+int idx = pgd_idx(level, granule_sz, iova);
+/*
+ * Get the ttb from concatenated structure.
+ * The offset is the idx * size of each ttb(number of ptes * (sizeof(pte))
+ */
+uint64_t baseaddr = extract64(cfg->s2cfg.vttb, 0, 48) + (1 << stride) *
+  idx * sizeof(uint64_t);
+dma_addr_t indexmask = SMMU_IDXMSK(inputsize, stride, level);
+
+baseaddr &= ~indexmask;
+
+/*
+ * If the input address of a transaction exceeds the size of the IAS, a
+ * stage 1 Address Size fault occurs.
+ * For AA64, IAS = OAS
+ */
+if (iova >= (1ULL << cfg->s2cfg.oas)) {
+info->type = SMMU_PTW_ERR_ADDR_SIZE;
+info->stage = 1;
+goto error_no_stage;
+}
+
+while (level < SMMU_LEVELS) {
+uint64_t subpage_size = 1ULL << level_shift(level, granule_sz);
+uint64_t mask = subpage_size - 1;
+uint32_t offset = iova_level_offset(iova, inputsize, level, 
granule_sz);
+uint64_t pte, gpa;
+dma_addr_t pte_addr = baseaddr + offset * sizeof(pte);
+uint8_t ap;
+
+if (get_pte(baseaddr, offset, &pte, info)) {
+goto error;
+}
+trace_smmu_ptw_level(stage, level, iova, subpage_size,
+ baseaddr, offset, pte);
+if (is_invalid_pte(pte) || is_reserved_pte(pte, level)) {
+trace_smmu_ptw_invalid_pte(stage, level, baseaddr,
+   pte_addr, offset, pte);
+break;
+}
+
+if (is_table_pte(pte, level)) {
+baseaddr = get_table_pte_address(pte, granule_sz);
+level++;
+continue;
+} else if (is_page_pte(pte, level)) {
+gpa = get_page_pte_address(pte, granule_sz);
+trace_smmu_ptw_page_pte(stage, level, iova,
+baseaddr, pte_addr, pte, gpa);
+} else {
+uint64_t block_size;
+
+gpa = get_block_pte_address(pte, level, granule_sz,
+&block_size);
+trace_smmu_ptw_block_pte(stage, level, baseaddr,
+ pte_addr, pte, iova, gpa,
+ block_size >> 20);
+}
+
+/*
+ * If S2AFFD and PTE.AF are 0 => fault. (5.2. Stream Table Entry)
+ * An Access fault takes priority over a Permission fault.
+ */
+if (!PTE_AF(pte) && !cfg->s2cfg.affd) {
+info->type = SMMU_PTW_ERR_ACCESS;
+goto error;
+}
+
+ap = PTE_AP(pte);
+if (is_permission_fault_s2(ap, perm)) {
+info->type = SMMU_PTW_ERR_PERMISSION;
+goto error;
+}
+
+/*
+ * The address output from the translation causes a stage 2 Address
+ * Size fault if it exceeds the effective PA output range.
+  

[PATCH v3 5/8] hw/ppc/pegasos2: Fix PCI interrupt routing

2023-02-26 Thread BALATON Zoltan
According to the PegasosII schematics the PCI interrupt lines are
connected to both the gpp pins of the Mv64361 north bridge and the
PINT pins of the VT8231 south bridge so guests can get interrupts from
either of these. So far we only had the MV64361 connections which
worked for on board devices but for additional PCI devices (such as
network or sound card added with -device) guest OSes expect interrupt
from the ISA IRQ 9 where the firmware routes these PCI interrupts in
VT8231 ISA bridge. After the previous patches we can now model this
and also remove the board specific connection from mv64361. Also
configure routing of these lines when using Virtual Open Firmware to
match board firmware for guests that expect this.

This fixes PCI interrupts on pegasos2 under Linux, MorphOS and AmigaOS.

Signed-off-by: BALATON Zoltan 
Tested-by: Rene Engel 
Reviewed-by: Daniel Henrique Barboza 
---
 hw/pci-host/mv64361.c |  4 
 hw/ppc/pegasos2.c | 26 +-
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c
index f43f33fbd9..3d9132f989 100644
--- a/hw/pci-host/mv64361.c
+++ b/hw/pci-host/mv64361.c
@@ -874,10 +874,6 @@ static void mv64361_realize(DeviceState *dev, Error **errp)
 }
 sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq);
 qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32);
-/* FIXME: PCI IRQ connections may be board specific */
-for (i = 0; i < PCI_NUM_PINS; i++) {
-s->pci[1].irq[i] = qdev_get_gpio_in_named(dev, "gpp", 12 + i);
-}
 }
 
 static void mv64361_reset(DeviceState *dev)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index a9563f4fb2..4e1476673b 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -74,6 +74,8 @@ struct Pegasos2MachineState {
 MachineState parent_obj;
 PowerPCCPU *cpu;
 DeviceState *mv;
+qemu_irq mv_pirq[PCI_NUM_PINS];
+qemu_irq via_pirq[PCI_NUM_PINS];
 Vof *vof;
 void *fdt_blob;
 uint64_t kernel_addr;
@@ -96,6 +98,15 @@ static void pegasos2_cpu_reset(void *opaque)
 }
 }
 
+static void pegasos2_pci_irq(void *opaque, int n, int level)
+{
+Pegasos2MachineState *pm = opaque;
+
+/* PCI interrupt lines are connected to both MV64361 and VT8231 */
+qemu_set_irq(pm->mv_pirq[n], level);
+qemu_set_irq(pm->via_pirq[n], level);
+}
+
 static void pegasos2_init(MachineState *machine)
 {
 Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
@@ -107,7 +118,7 @@ static void pegasos2_init(MachineState *machine)
 I2CBus *i2c_bus;
 const char *fwname = machine->firmware ?: PROM_FILENAME;
 char *filename;
-int sz;
+int i, sz;
 uint8_t *spd_data;
 
 /* init CPU */
@@ -157,11 +168,18 @@ static void pegasos2_init(MachineState *machine)
 /* Marvell Discovery II system controller */
 pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
   qdev_get_gpio_in(DEVICE(pm->cpu), 
PPC6xx_INPUT_INT)));
+for (i = 0; i < PCI_NUM_PINS; i++) {
+pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->mv, "gpp", 12 + i);
+}
 pci_bus = mv64361_get_pci_bus(pm->mv, 1);
+pci_bus_irqs(pci_bus, pegasos2_pci_irq, pm, PCI_NUM_PINS);
 
 /* VIA VT8231 South Bridge (multifunction PCI device) */
 via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0),
  true, TYPE_VT8231_ISA));
+for (i = 0; i < PCI_NUM_PINS; i++) {
+pm->via_pirq[i] = qdev_get_gpio_in_named(DEVICE(via), "pirq", i);
+}
 object_property_add_alias(OBJECT(machine), "rtc-time",
   object_resolve_path_component(via, "rtc"),
   "date");
@@ -268,6 +286,12 @@ static void pegasos2_machine_reset(MachineState *machine, 
ShutdownCause reason)
   PCI_INTERRUPT_LINE, 2, 0x9);
 pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
   0x50, 1, 0x2);
+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+  0x55, 1, 0x90);
+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+  0x56, 1, 0x99);
+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+  0x57, 1, 0x90);
 
 pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 1) << 8) |
   PCI_INTERRUPT_LINE, 2, 0x109);
-- 
2.30.7




[PATCH v3 1/8] hw/display/sm501: Implement more 2D raster operations

2023-02-26 Thread BALATON Zoltan
Add simple implementation for two raster operations that are used by
AmigaOS which fixes graphics problems in some programs using these.

Signed-off-by: BALATON Zoltan 
Reported-by: Rene Engel 
Tested-by: Rene Engel 
Reviewed-by: Daniel Henrique Barboza 
---
These are documented for example at:
https://learn.microsoft.com/en-us/windows/win32/gdi/ternary-raster-operations

 hw/display/sm501.c | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index e1d0591d36..58bc9701ee 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -753,7 +753,7 @@ static void sm501_2d_operation(SM501State *s)
 }
 
 if ((rop_mode && rop == 0x5) || (!rop_mode && rop == 0x55)) {
-/* Invert dest, is there a way to do this with pixman? */
+/* DSTINVERT, is there a way to do this with pixman? */
 unsigned int x, y, i;
 uint8_t *d = s->local_mem + dst_base;
 
@@ -763,6 +763,34 @@ static void sm501_2d_operation(SM501State *s)
 stn_he_p(&d[i], bypp, ~ldn_he_p(&d[i], bypp));
 }
 }
+} else if (!rop_mode && rop == 0x99) {
+/* DSxn, is there a way to do this with pixman? */
+unsigned int x, y, i, j;
+uint8_t *sp = s->local_mem + src_base;
+uint8_t *d = s->local_mem + dst_base;
+
+for (y = 0; y < height; y++) {
+i = (dst_x + (dst_y + y) * dst_pitch) * bypp;
+j = (src_x + (src_y + y) * src_pitch) * bypp;
+for (x = 0; x < width; x++, i += bypp, j += bypp) {
+stn_he_p(&d[i], bypp,
+ ~(ldn_he_p(&sp[j], bypp) ^ ldn_he_p(&d[i], 
bypp)));
+}
+}
+} else if (!rop_mode && rop == 0xee) {
+/* SRCPAINT, is there a way to do this with pixman? */
+unsigned int x, y, i, j;
+uint8_t *sp = s->local_mem + src_base;
+uint8_t *d = s->local_mem + dst_base;
+
+for (y = 0; y < height; y++) {
+i = (dst_x + (dst_y + y) * dst_pitch) * bypp;
+j = (src_x + (src_y + y) * src_pitch) * bypp;
+for (x = 0; x < width; x++, i += bypp, j += bypp) {
+stn_he_p(&d[i], bypp,
+ ldn_he_p(&sp[j], bypp) | ldn_he_p(&d[i], bypp));
+}
+}
 } else {
 /* Do copy src for unimplemented ops, better than unpainted area */
 if ((rop_mode && (rop != 0xc || rop2_source_is_pattern)) ||
-- 
2.30.7




[PATCH v3 2/8] hw/display/sm501: Add fallbacks to pixman routines

2023-02-26 Thread BALATON Zoltan
Pixman may return false if it does not have a suitable implementation.
Add fallbacks to handle such cases.

Signed-off-by: BALATON Zoltan 
Reported-by: Rene Engel 
Tested-by: Rene Engel 
---
 hw/display/sm501.c | 75 --
 1 file changed, 52 insertions(+), 23 deletions(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 58bc9701ee..23c4418e19 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -691,7 +691,7 @@ static void sm501_2d_operation(SM501State *s)
 unsigned int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF;
 int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0;
 int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt);
-bool overlap = false;
+bool overlap = false, fallback = false;
 
 if ((s->twoD_stretch >> 16) & 0xF) {
 qemu_log_mask(LOG_UNIMP, "sm501: only XY addressing is supported.\n");
@@ -834,25 +834,48 @@ static void sm501_2d_operation(SM501State *s)
 if (tmp_stride * sizeof(uint32_t) * height > sizeof(tmp_buf)) {
 tmp = g_malloc(tmp_stride * sizeof(uint32_t) * height);
 }
-pixman_blt((uint32_t *)&s->local_mem[src_base], tmp,
-   src_pitch * bypp / sizeof(uint32_t),
-   tmp_stride, 8 * bypp, 8 * bypp,
-   src_x, src_y, 0, 0, width, height);
-pixman_blt(tmp, (uint32_t *)&s->local_mem[dst_base],
-   tmp_stride,
-   dst_pitch * bypp / sizeof(uint32_t),
-   8 * bypp, 8 * bypp,
-   0, 0, dst_x, dst_y, width, height);
+fallback = !pixman_blt((uint32_t *)&s->local_mem[src_base],
+   tmp,
+   src_pitch * bypp / sizeof(uint32_t),
+   tmp_stride,
+   8 * bypp, 8 * bypp,
+   src_x, src_y, 0, 0, width, height);
+if (!fallback) {
+fallback = !pixman_blt(tmp,
+   (uint32_t *)&s->local_mem[dst_base],
+   tmp_stride,
+   dst_pitch * bypp / sizeof(uint32_t),
+   8 * bypp, 8 * bypp,
+   0, 0, dst_x, dst_y, width, height);
+}
 if (tmp != tmp_buf) {
 g_free(tmp);
 }
 } else {
-pixman_blt((uint32_t *)&s->local_mem[src_base],
-   (uint32_t *)&s->local_mem[dst_base],
-   src_pitch * bypp / sizeof(uint32_t),
-   dst_pitch * bypp / sizeof(uint32_t),
-   8 * bypp, 8 * bypp,
-   src_x, src_y, dst_x, dst_y, width, height);
+fallback = !pixman_blt((uint32_t *)&s->local_mem[src_base],
+   (uint32_t *)&s->local_mem[dst_base],
+   src_pitch * bypp / sizeof(uint32_t),
+   dst_pitch * bypp / sizeof(uint32_t),
+   8 * bypp, 8 * bypp, src_x, src_y,
+   dst_x, dst_y, width, height);
+}
+if (fallback) {
+uint8_t *sp = s->local_mem + src_base;
+uint8_t *d = s->local_mem + dst_base;
+unsigned int y, i, j;
+for (y = 0; y < height; y++) {
+if (overlap) { /* overlap also means rtl */
+i = (dst_y + height - 1 - y) * dst_pitch;
+i = (dst_x + i) * bypp;
+j = (src_y + height - 1 - y) * src_pitch;
+j = (src_x + j) * bypp;
+memmove(&d[i], &sp[j], width * bypp);
+} else {
+i = (dst_x + (dst_y + y) * dst_pitch) * bypp;
+j = (src_x + (src_y + y) * src_pitch) * bypp;
+memcpy(&d[i], &sp[j], width * bypp);
+}
+}
 }
 }
 break;
@@ -867,13 +890,19 @@ static void sm501_2d_operation(SM501State *s)
 color = cpu_to_le16(color);
 }
 
-if (width == 1 && height == 1) {
-unsigned int i = (dst_x + dst_y * dst_pitch) * bypp;
-stn_he_p(&s->local_mem[dst_base + i], bypp, color);
-} else {
-pixman_fill((uint32_t *)&s->local_mem[dst_base],
-dst_pitch * bypp / sizeof(uint32_t),
-8 * bypp, dst_x, dst_y, width, height, color);
+if ((width == 1 && height == 1) ||
+!pixman_fill((uint32

[PATCH v3 7/8] hw/audio/ac97: Split off some definitions to a header

2023-02-26 Thread BALATON Zoltan
These can be shared with other AC97 implementations.

Signed-off-by: BALATON Zoltan 
---
 hw/audio/ac97.c | 43 +---
 hw/audio/ac97.h | 65 +
 2 files changed, 66 insertions(+), 42 deletions(-)
 create mode 100644 hw/audio/ac97.h

diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c
index 364cdfa733..b3fb10284c 100644
--- a/hw/audio/ac97.c
+++ b/hw/audio/ac97.c
@@ -26,43 +26,7 @@
 #include "qemu/module.h"
 #include "sysemu/dma.h"
 #include "qom/object.h"
-
-enum {
-AC97_Reset = 0x00,
-AC97_Master_Volume_Mute= 0x02,
-AC97_Headphone_Volume_Mute = 0x04,
-AC97_Master_Volume_Mono_Mute   = 0x06,
-AC97_Master_Tone_RL= 0x08,
-AC97_PC_BEEP_Volume_Mute   = 0x0A,
-AC97_Phone_Volume_Mute = 0x0C,
-AC97_Mic_Volume_Mute   = 0x0E,
-AC97_Line_In_Volume_Mute   = 0x10,
-AC97_CD_Volume_Mute= 0x12,
-AC97_Video_Volume_Mute = 0x14,
-AC97_Aux_Volume_Mute   = 0x16,
-AC97_PCM_Out_Volume_Mute   = 0x18,
-AC97_Record_Select = 0x1A,
-AC97_Record_Gain_Mute  = 0x1C,
-AC97_Record_Gain_Mic_Mute  = 0x1E,
-AC97_General_Purpose   = 0x20,
-AC97_3D_Control= 0x22,
-AC97_AC_97_RESERVED= 0x24,
-AC97_Powerdown_Ctrl_Stat   = 0x26,
-AC97_Extended_Audio_ID = 0x28,
-AC97_Extended_Audio_Ctrl_Stat  = 0x2A,
-AC97_PCM_Front_DAC_Rate= 0x2C,
-AC97_PCM_Surround_DAC_Rate = 0x2E,
-AC97_PCM_LFE_DAC_Rate  = 0x30,
-AC97_PCM_LR_ADC_Rate   = 0x32,
-AC97_MIC_ADC_Rate  = 0x34,
-AC97_6Ch_Vol_C_LFE_Mute= 0x36,
-AC97_6Ch_Vol_L_R_Surround_Mute = 0x38,
-AC97_Vendor_Reserved   = 0x58,
-AC97_Sigmatel_Analog   = 0x6c, /* We emulate a Sigmatel codec */
-AC97_Sigmatel_Dac2Invert   = 0x6e, /* We emulate a Sigmatel codec */
-AC97_Vendor_ID1= 0x7c,
-AC97_Vendor_ID2= 0x7e
-};
+#include "ac97.h"
 
 #define SOFT_VOLUME
 #define SR_FIFOE 16 /* rwc */
@@ -121,11 +85,6 @@ enum {
 #define BD_IOC (1 << 31)
 #define BD_BUP (1 << 30)
 
-#define EACS_VRA 1
-#define EACS_VRM 8
-
-#define MUTE_SHIFT 15
-
 #define TYPE_AC97 "AC97"
 OBJECT_DECLARE_SIMPLE_TYPE(AC97LinkState, AC97)
 
diff --git a/hw/audio/ac97.h b/hw/audio/ac97.h
new file mode 100644
index 00..0358b56ff4
--- /dev/null
+++ b/hw/audio/ac97.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2006 InnoTek Systemberatung GmbH
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software Foundation,
+ * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
+ * distribution. VirtualBox OSE is distributed in the hope that it will
+ * be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * If you received this file as part of a commercial VirtualBox
+ * distribution, then only the terms of your commercial VirtualBox
+ * license agreement apply instead of the previous paragraph.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#ifndef AC97_H
+#define AC97_H
+
+enum {
+AC97_Reset = 0x00,
+AC97_Master_Volume_Mute= 0x02,
+AC97_Headphone_Volume_Mute = 0x04,
+AC97_Master_Volume_Mono_Mute   = 0x06,
+AC97_Master_Tone_RL= 0x08,
+AC97_PC_BEEP_Volume_Mute   = 0x0A,
+AC97_Phone_Volume_Mute = 0x0C,
+AC97_Mic_Volume_Mute   = 0x0E,
+AC97_Line_In_Volume_Mute   = 0x10,
+AC97_CD_Volume_Mute= 0x12,
+AC97_Video_Volume_Mute = 0x14,
+AC97_Aux_Volume_Mute   = 0x16,
+AC97_PCM_Out_Volume_Mute   = 0x18,
+AC97_Record_Select = 0x1A,
+AC97_Record_Gain_Mute  = 0x1C,
+AC97_Record_Gain_Mic_Mute  = 0x1E,
+AC97_General_Purpose   = 0x20,
+AC97_3D_Control= 0x22,
+AC97_AC_97_RESERVED= 0x24,
+AC97_Powerdown_Ctrl_Stat   = 0x26,
+AC97_Extended_Audio_ID = 0x28,
+AC97_Extended_Audio_Ctrl_Stat  = 0x2A,
+AC97_PCM_Front_DAC_Rate= 0x2C,
+AC97_PCM_Surround_DAC_Rate = 0x2E,
+AC97_PCM_LFE_DAC_Rate  = 0x30,
+AC97_PCM_LR_ADC_Rate   = 0x32,
+AC97_MIC_ADC_Rate  = 0x34,
+AC97_6Ch_Vol_C_LFE_Mute= 0x36,
+AC97_6Ch_Vol_L_R_Surround_Mute = 0x38,
+AC97_Vendor_Reserved   = 0x58,
+AC97_Sigmatel_Analog   = 0x6c, /* We emulate a Sigmatel codec */
+AC97_Sigmatel_Dac2Invert   = 0x6e, /* We emulate a Sigmatel codec */
+AC97_Vendor_ID1  

[PATCH v3 3/8] hw/display/sm501: Add debug property to control pixman usage

2023-02-26 Thread BALATON Zoltan
Add a property to allow disabling pixman and always use the fallbacks
for different operations which is useful for testing different drawing
methods or debugging pixman related issues.

Signed-off-by: BALATON Zoltan 
---
 hw/display/sm501.c | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 23c4418e19..f2f7f26751 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -464,6 +464,7 @@ typedef struct SM501State {
 uint32_t last_width;
 uint32_t last_height;
 bool do_full_update; /* perform a full update next time */
+uint8_t use_pixman;
 I2CBus *i2c_bus;
 
 /* mmio registers */
@@ -826,7 +827,7 @@ static void sm501_2d_operation(SM501State *s)
 de = db + (width + (height - 1) * dst_pitch) * bypp;
 overlap = (db < se && sb < de);
 }
-if (overlap) {
+if (overlap && (s->use_pixman & BIT(2))) {
 /* pixman can't do reverse blit: copy via temporary */
 int tmp_stride = DIV_ROUND_UP(width * bypp, sizeof(uint32_t));
 uint32_t *tmp = tmp_buf;
@@ -851,13 +852,15 @@ static void sm501_2d_operation(SM501State *s)
 if (tmp != tmp_buf) {
 g_free(tmp);
 }
-} else {
+} else if (!overlap && (s->use_pixman & BIT(1))) {
 fallback = !pixman_blt((uint32_t *)&s->local_mem[src_base],
(uint32_t *)&s->local_mem[dst_base],
src_pitch * bypp / sizeof(uint32_t),
dst_pitch * bypp / sizeof(uint32_t),
8 * bypp, 8 * bypp, src_x, src_y,
dst_x, dst_y, width, height);
+} else {
+fallback = true;
 }
 if (fallback) {
 uint8_t *sp = s->local_mem + src_base;
@@ -890,7 +893,7 @@ static void sm501_2d_operation(SM501State *s)
 color = cpu_to_le16(color);
 }
 
-if ((width == 1 && height == 1) ||
+if (!(s->use_pixman & BIT(0)) || (width == 1 && height == 1) ||
 !pixman_fill((uint32_t *)&s->local_mem[dst_base],
  dst_pitch * bypp / sizeof(uint32_t), 8 * bypp,
  dst_x, dst_y, width, height, color)) {
@@ -2039,6 +2042,7 @@ static void sm501_realize_sysbus(DeviceState *dev, Error 
**errp)
 static Property sm501_sysbus_properties[] = {
 DEFINE_PROP_UINT32("vram-size", SM501SysBusState, vram_size, 0),
 DEFINE_PROP_UINT32("base", SM501SysBusState, base, 0),
+DEFINE_PROP_UINT8("x-pixman", SM501SysBusState, state.use_pixman, 7),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -2122,6 +2126,7 @@ static void sm501_realize_pci(PCIDevice *dev, Error 
**errp)
 
 static Property sm501_pci_properties[] = {
 DEFINE_PROP_UINT32("vram-size", SM501PCIState, vram_size, 64 * MiB),
+DEFINE_PROP_UINT8("x-pixman", SM501PCIState, state.use_pixman, 7),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -2162,11 +2167,18 @@ static void sm501_pci_class_init(ObjectClass *klass, 
void *data)
 dc->vmsd = &vmstate_sm501_pci;
 }
 
+static void sm501_pci_init(Object *o)
+{
+object_property_set_description(o, "x-pixman", "Use pixman for: "
+"1: fill, 2: blit, 4: overlap blit");
+}
+
 static const TypeInfo sm501_pci_info = {
 .name  = TYPE_PCI_SM501,
 .parent= TYPE_PCI_DEVICE,
 .instance_size = sizeof(SM501PCIState),
 .class_init= sm501_pci_class_init,
+.instance_init = sm501_pci_init,
 .interfaces = (InterfaceInfo[]) {
 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
 { },
-- 
2.30.7




[PATCH v3 8/8] hw/audio/via-ac97: Basic implementation of audio playback

2023-02-26 Thread BALATON Zoltan
Add basic implementation of the AC'97 sound part used in VIA south
bridge chips. Not all features of the device is emulated, only one
playback channel is supported for now but this is enough to get sound
output from some guests using this device on pegasos2.

Signed-off-by: BALATON Zoltan 
Tested-by: Rene Engel 
---
v3: Fixed CLEN_LEN mask, add check to avoid runaway DMA and some
tweaks to PCI config regs which now make it work with AmigaOS too.
This is probably as good as it gets for QEMU 8.0

 hw/audio/trace-events |   6 +
 hw/audio/via-ac97.c   | 455 +-
 hw/isa/trace-events   |   1 +
 hw/isa/vt82c686.c |   2 +-
 include/hw/isa/vt82c686.h |  25 +++
 5 files changed, 482 insertions(+), 7 deletions(-)

diff --git a/hw/audio/trace-events b/hw/audio/trace-events
index e0e71cd9b1..4dec48a4fd 100644
--- a/hw/audio/trace-events
+++ b/hw/audio/trace-events
@@ -11,3 +11,9 @@ hda_audio_running(const char *stream, int nr, bool running) 
"st %s, nr %d, run %
 hda_audio_format(const char *stream, int chan, const char *fmt, int freq) "st 
%s, %d x %s @ %d Hz"
 hda_audio_adjust(const char *stream, int pos) "st %s, pos %d"
 hda_audio_overrun(const char *stream) "st %s"
+
+#via-ac97.c
+via_ac97_codec_write(uint8_t addr, uint16_t val) "0x%x <- 0x%x"
+via_ac97_sgd_fetch(uint32_t curr, uint32_t addr, char stop, char eol, char 
flag, uint32_t len) "curr=0x%x addr=0x%x %c%c%c len=%d"
+via_ac97_sgd_read(uint64_t addr, unsigned size, uint64_t val) "0x%"PRIx64" %d 
-> 0x%"PRIx64
+via_ac97_sgd_write(uint64_t addr, unsigned size, uint64_t val) "0x%"PRIx64" %d 
<- 0x%"PRIx64
diff --git a/hw/audio/via-ac97.c b/hw/audio/via-ac97.c
index d1a856f63d..676254b7a4 100644
--- a/hw/audio/via-ac97.c
+++ b/hw/audio/via-ac97.c
@@ -1,39 +1,482 @@
 /*
  * VIA south bridges sound support
  *
+ * Copyright (c) 2022-2023 BALATON Zoltan
+ *
  * This work is licensed under the GNU GPL license version 2 or later.
  */
 
 /*
- * TODO: This is entirely boiler plate just registering empty PCI devices
- * with the right ID guests expect, functionality should be added here.
+ * TODO: This is only a basic implementation of one audio playback channel
+ *   more functionality should be added here.
  */
 
 #include "qemu/osdep.h"
+#include "qemu/log.h"
 #include "hw/isa/vt82c686.h"
-#include "hw/pci/pci_device.h"
+#include "ac97.h"
+#include "trace.h"
+
+#define CLEN_IS_EOL(x)  ((x)->clen & BIT(31))
+#define CLEN_IS_FLAG(x) ((x)->clen & BIT(30))
+#define CLEN_IS_STOP(x) ((x)->clen & BIT(29))
+#define CLEN_LEN(x) ((x)->clen & 0xff)
+
+#define STAT_ACTIVE BIT(7)
+#define STAT_PAUSED BIT(6)
+#define STAT_TRIG   BIT(3)
+#define STAT_STOP   BIT(2)
+#define STAT_EOLBIT(1)
+#define STAT_FLAG   BIT(0)
+
+#define CNTL_START  BIT(7)
+#define CNTL_TERM   BIT(6)
+#define CNTL_PAUSE  BIT(3)
+
+static void open_voice_out(ViaAC97State *s);
+
+static uint16_t codec_rates[] = { 8000, 11025, 16000, 22050, 32000, 44100,
+  48000 };
+
+#define CODEC_REG(s, o)  ((s)->codec_regs[(o) / 2])
+#define CODEC_VOL(vol, mask)  ((255 * ((vol) & mask)) / mask)
+
+static void codec_volume_set_out(ViaAC97State *s)
+{
+int lvol, rvol, mute;
+
+lvol = 255 - CODEC_VOL(CODEC_REG(s, AC97_Master_Volume_Mute) >> 8, 0x1f);
+lvol *= 255 - CODEC_VOL(CODEC_REG(s, AC97_PCM_Out_Volume_Mute) >> 8, 0x1f);
+lvol /= 255;
+rvol = 255 - CODEC_VOL(CODEC_REG(s, AC97_Master_Volume_Mute), 0x1f);
+rvol *= 255 - CODEC_VOL(CODEC_REG(s, AC97_PCM_Out_Volume_Mute), 0x1f);
+rvol /= 255;
+mute = CODEC_REG(s, AC97_Master_Volume_Mute) >> MUTE_SHIFT;
+mute |= CODEC_REG(s, AC97_PCM_Out_Volume_Mute) >> MUTE_SHIFT;
+AUD_set_volume_out(s->vo, mute, lvol, rvol);
+}
+
+static void codec_reset(ViaAC97State *s)
+{
+memset(s->codec_regs, 0, sizeof(s->codec_regs));
+CODEC_REG(s, AC97_Reset) = 0x6a90;
+CODEC_REG(s, AC97_Master_Volume_Mute) = 0x8000;
+CODEC_REG(s, AC97_Headphone_Volume_Mute) = 0x8000;
+CODEC_REG(s, AC97_Master_Volume_Mono_Mute) = 0x8000;
+CODEC_REG(s, AC97_Phone_Volume_Mute) = 0x8008;
+CODEC_REG(s, AC97_Mic_Volume_Mute) = 0x8008;
+CODEC_REG(s, AC97_Line_In_Volume_Mute) = 0x8808;
+CODEC_REG(s, AC97_CD_Volume_Mute) = 0x8808;
+CODEC_REG(s, AC97_Video_Volume_Mute) = 0x8808;
+CODEC_REG(s, AC97_Aux_Volume_Mute) = 0x8808;
+CODEC_REG(s, AC97_PCM_Out_Volume_Mute) = 0x8808;
+CODEC_REG(s, AC97_Record_Gain_Mute) = 0x8000;
+CODEC_REG(s, AC97_Powerdown_Ctrl_Stat) = 0x000f;
+CODEC_REG(s, AC97_Extended_Audio_ID) = 0x0a05;
+CODEC_REG(s, AC97_Extended_Audio_Ctrl_Stat) = 0x0400;
+CODEC_REG(s, AC97_PCM_Front_DAC_Rate) = 48000;
+CODEC_REG(s, AC97_PCM_LR_ADC_Rate) = 48000;
+/* Sigmatel 9766 (STAC9766) */
+CODEC_REG(s, AC97_Vendor_ID1) = 0x8384;
+CODEC_REG(s, AC97_Vendor_ID2) = 0x7666;
+}
+
+static uint16_t codec_read(ViaAC97State *s, uint8_t addr)
+{
+return CODEC_REG(s, addr);
+}
+
+static void codec_write(ViaAC97S

[PATCH v3 4/8] hw/isa/vt82c686: Implement PCI IRQ routing

2023-02-26 Thread BALATON Zoltan
From: Bernhard Beschow 

The real VIA south bridges implement a PCI IRQ router which is configured
by the BIOS or the OS. In order to respect these configurations, QEMU
needs to implement it as well.

Note: The implementation was taken from piix4_set_irq() in hw/isa/piix4.

Signed-off-by: Bernhard Beschow 
[balaton: declare gpio inputs instead of changing pci bus irqs so it can
 be connected in board code; remove some empty lines]
Signed-off-by: BALATON Zoltan 
Tested-by: Rene Engel 
---
 hw/isa/vt82c686.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 3f9bd0c04d..4025f9bcdc 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -604,6 +604,44 @@ static void via_isa_request_i8259_irq(void *opaque, int 
irq, int level)
 qemu_set_irq(s->cpu_intr, level);
 }
 
+static int via_isa_get_pci_irq(const ViaISAState *s, int irq_num)
+{
+switch (irq_num) {
+case 0:
+return s->dev.config[0x55] >> 4;
+case 1:
+return s->dev.config[0x56] & 0xf;
+case 2:
+return s->dev.config[0x56] >> 4;
+case 3:
+return s->dev.config[0x57] >> 4;
+}
+return 0;
+}
+
+static void via_isa_set_pci_irq(void *opaque, int irq_num, int level)
+{
+ViaISAState *s = opaque;
+PCIBus *bus = pci_get_bus(&s->dev);
+int pic_irq;
+
+/* now we change the pic irq level according to the via irq mappings */
+/* XXX: optimize */
+pic_irq = via_isa_get_pci_irq(s, irq_num);
+if (pic_irq < ISA_NUM_IRQS) {
+int i, pic_level;
+
+/* The pic level is the logical OR of all the PCI irqs mapped to it. */
+pic_level = 0;
+for (i = 0; i < PCI_NUM_PINS; i++) {
+if (pic_irq == via_isa_get_pci_irq(s, i)) {
+pic_level |= pci_bus_get_irq_level(bus, i);
+}
+}
+qemu_set_irq(s->isa_irqs[pic_irq], pic_level);
+}
+}
+
 static void via_isa_realize(PCIDevice *d, Error **errp)
 {
 ViaISAState *s = VIA_ISA(d);
@@ -614,6 +652,7 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
 int i;
 
 qdev_init_gpio_out(dev, &s->cpu_intr, 1);
+qdev_init_gpio_in_named(dev, via_isa_set_pci_irq, "pirq", PCI_NUM_PINS);
 isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
 isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d),
   errp);
-- 
2.30.7




[PATCH v3 0/8] Pegasos2 fixes and audio output support

2023-02-26 Thread BALATON Zoltan
Hello,

This is marked v3 to avoid confusion with previously separate patches
that already had v2, even if the series had no v2 yet.

This series now includes all patches needed to get AmigaOS 4.1 run
well on pegasos2 and add audio output to this board. It has 3 parts:
patches 1-3 improve hw/display/sm501 model to avoid graphics problems
that were present with AmigaOS; patches 4-6 fix PCI interrupt routing
in VIA VT8231 model and in pegasos2 board that fixes PCI cards such as
network or sound card not working before; finally patches 7-8 add
basic implementation of the via-ac97 audio part of VT8231 (also used
on VT82C686B) for output that is the default audio device on pegasos2.

This version was re-tested by Rene Engel with latest AmigaOS version
and runs as well as my original series did (posted a video with that
before). This works now on an M1 MacStudio on macOS where it was
unusable before. I've also tested it on Linux x86_64 with older
AmigaOS version that also boots and makes sound and verified MorphOS
still boots and also has sound now.

One known problem with this version that includes Berhard's
alternative vt82c686 patches is with MorphOS which uses level
sensitive mode of the i8259 PIC that QEMU does not support so it hangs
when multiple devices try to raise a shared IRQ. I could work around
that in my otiginal series (see here:
https://lists.nongnu.org/archive/html/qemu-ppc/2023-02/msg00403.html )
where this works and was also tested, that version is available here:
https://osdn.net/projects/qmiga/scm/git/qemu/tree/pegasos2/
but I could not convince Bernhard so I now expect him to provide a
work around for that. This isn't a blocker though as MorphOS already
runs on mac99 and sam460ex and only available as a time limited demo
(they only sell licenses for real hardware) so not really usable apart
from testing anyway so getting it running on pegasos2 would be nice
but not a prioriey, more important is that AmigaOS runs for which this
is the only viable machine as sam460ex version runs much slower. So
I'd like this to be merged for 8.0 as it is now or only minor chnages
(or alternatively we can return to my series which was also tested the
same way and apart from different VIA IRQ router modelling contains
the same patches).

Please review and let me know who will take care of merging this for 8.0.

Regards,
BALATON Zoltan

BALATON Zoltan (6):
  hw/display/sm501: Implement more 2D raster operations
  hw/display/sm501: Add fallbacks to pixman routines
  hw/display/sm501: Add debug property to control pixman usage
  hw/ppc/pegasos2: Fix PCI interrupt routing
  hw/audio/ac97: Split off some definitions to a header
  hw/audio/via-ac97: Basic implementation of audio playback

Bernhard Beschow (2):
  hw/isa/vt82c686: Implement PCI IRQ routing
  hw/usb/vt82c686-uhci-pci: Use PCI IRQ routing

 hw/audio/ac97.c|  43 +---
 hw/audio/ac97.h|  65 ++
 hw/audio/trace-events  |   6 +
 hw/audio/via-ac97.c| 455 -
 hw/display/sm501.c | 119 --
 hw/isa/trace-events|   1 +
 hw/isa/vt82c686.c  |  41 +++-
 hw/pci-host/mv64361.c  |   4 -
 hw/ppc/pegasos2.c  |  26 ++-
 hw/usb/vt82c686-uhci-pci.c |  12 -
 include/hw/isa/vt82c686.h  |  25 ++
 11 files changed, 706 insertions(+), 91 deletions(-)
 create mode 100644 hw/audio/ac97.h

-- 
2.30.7




[PATCH v3 6/8] hw/usb/vt82c686-uhci-pci: Use PCI IRQ routing

2023-02-26 Thread BALATON Zoltan
From: Bernhard Beschow 

According to the PCI specification, PCI_INTERRUPT_LINE shall have no
effect on hardware operations. Now that the VIA south bridges implement
the internal PCI interrupt router let's be more conformant to the PCI
specification.

Signed-off-by: Bernhard Beschow 
Signed-off-by: BALATON Zoltan 
Tested-by: Rene Engel 
---
 hw/usb/vt82c686-uhci-pci.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/hw/usb/vt82c686-uhci-pci.c b/hw/usb/vt82c686-uhci-pci.c
index 46a901f56f..b4884c9011 100644
--- a/hw/usb/vt82c686-uhci-pci.c
+++ b/hw/usb/vt82c686-uhci-pci.c
@@ -1,17 +1,7 @@
 #include "qemu/osdep.h"
-#include "hw/irq.h"
 #include "hw/isa/vt82c686.h"
 #include "hcd-uhci.h"
 
-static void uhci_isa_set_irq(void *opaque, int irq_num, int level)
-{
-UHCIState *s = opaque;
-uint8_t irq = pci_get_byte(s->dev.config + PCI_INTERRUPT_LINE);
-if (irq > 0 && irq < 15) {
-via_isa_set_irq(pci_get_function_0(&s->dev), irq, level);
-}
-}
-
 static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
 {
 UHCIState *s = UHCI(dev);
@@ -25,8 +15,6 @@ static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error 
**errp)
 pci_set_long(pci_conf + 0xc0, 0x2000);
 
 usb_uhci_common_realize(dev, errp);
-object_unref(s->irq);
-s->irq = qemu_allocate_irq(uhci_isa_set_irq, s, 0);
 }
 
 static UHCIInfo uhci_info[] = {
-- 
2.30.7




Re: [PATCH] hw/display/sm501: Implement more 2D raster operations

2023-02-26 Thread BALATON Zoltan

On Sun, 26 Feb 2023, Philippe Mathieu-Daudé wrote:

On 16/2/23 15:40, BALATON Zoltan wrote:

Add simple implementation for two raster operations that are used by
AmigaOS which fixes graphics problems in some progtams using these.


Typo "programs".


Fixed in v3 (was just in time for that :-) ).


Signed-off-by: BALATON Zoltan 
---
For definitions of these see:
https://learn.microsoft.com/en-us/windows/win32/gdi/ternary-raster-operations


Comment worth being in the commit description IMO.


I don't think adding URLs to the source that can remain the same for years 
while URLs can go away is a good idea. It's only here to help review.


Regards,
BALATON Zoltan


  hw/display/sm501.c | 30 +-
  1 file changed, 29 insertions(+), 1 deletion(-)





Re: [PATCH 4/5] hw/audio/ac97: Split off some definitions to a header

2023-02-26 Thread BALATON Zoltan

On Sat, 25 Feb 2023, Philippe Mathieu-Daudé wrote:

On 21/2/23 19:44, BALATON Zoltan wrote:

These can be shared with other AC97 implementations.

Signed-off-by: BALATON Zoltan 
---
  hw/audio/ac97.c | 43 +---
  hw/audio/ac97.h | 65 +
  2 files changed, 66 insertions(+), 42 deletions(-)
  create mode 100644 hw/audio/ac97.h


Reviewed-by: Philippe Mathieu-Daudé 


Sorry missed this one, I'll add to next version if needed.

Re: [PATCH v3 7/8] hw/audio/ac97: Split off some definitions to a header

2023-02-26 Thread Philippe Mathieu-Daudé

On 25/1/22 20:48, BALATON Zoltan wrote:

These can be shared with other AC97 implementations.

Signed-off-by: BALATON Zoltan 
---
  hw/audio/ac97.c | 43 +---
  hw/audio/ac97.h | 65 +
  2 files changed, 66 insertions(+), 42 deletions(-)
  create mode 100644 hw/audio/ac97.h


Please carry previous tags.

Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH 3/5] hw/ppc/pegasos2: Fix PCI interrupt routing

2023-02-26 Thread BALATON Zoltan

On Sat, 25 Feb 2023, Philippe Mathieu-Daudé wrote:

On 21/2/23 19:44, BALATON Zoltan wrote:

According to the PegasosII schematics the PCI interrupt lines are
connected to both the gpp pins of the Mv64361 north bridge and the
PINT pins of the VT8231 south bridge so guests can get interrupts from
either of these. So far we only had the MV64361 connections which
worked for on board devices but for additional PCI devices (such as
network or sound card added with -device) guest OSes expect interrupt
from the ISA IRQ 9 where the firmware routes these PCI interrupts in
VT8231 ISA bridge. After the previous patches we can now model this
and also remove the board specific connection from mv64361. Also
configure routing of these lines when using Virtual Open Firmware to
match board firmware for guests that expect this.

This fixes PCI interrupts on pegasos2 under Linux, MorphOS and AmigaOS.

Signed-off-by: BALATON Zoltan 
---
  hw/pci-host/mv64361.c |  4 
  hw/ppc/pegasos2.c | 26 +-
  2 files changed, 25 insertions(+), 5 deletions(-)




+static void pegasos2_pci_irq(void *opaque, int n, int level)
+{
+Pegasos2MachineState *pm = opaque;
+
+/* PCI interrupt lines are connected to both MV64361 and VT8231 */
+qemu_set_irq(pm->mv_pirq[n], level);
+qemu_set_irq(pm->via_pirq[n], level);
+}


See TYPE_SPLIT_IRQ.


I've checked it but instead of storing 8 qemi_irqs in machine state we 
would end up storing additional 2 DeviceStates and had to use cryptic 
qemu_gpio and qdev commands to achieve the same in a much more convoluted 
and longer way. So I concluded that if you have to split an irq into more 
than two or have variable number of destinations then split-irq would be 
useful but it's an overkill for this simple case so I'd stay with the 
simple solution that's easy to understand.


Regards,
BALATON Zoltan

Re: [PATCH v3 4/8] hw/isa/vt82c686: Implement PCI IRQ routing

2023-02-26 Thread Philippe Mathieu-Daudé

On 25/2/23 19:11, BALATON Zoltan wrote:

From: Bernhard Beschow 

The real VIA south bridges implement a PCI IRQ router which is configured
by the BIOS or the OS. In order to respect these configurations, QEMU
needs to implement it as well.

Note: The implementation was taken from piix4_set_irq() in hw/isa/piix4.

Signed-off-by: Bernhard Beschow 
[balaton: declare gpio inputs instead of changing pci bus irqs so it can
  be connected in board code; remove some empty lines]
Signed-off-by: BALATON Zoltan 
Tested-by: Rene Engel 
---
  hw/isa/vt82c686.c | 39 +++
  1 file changed, 39 insertions(+)



+static int via_isa_get_pci_irq(const ViaISAState *s, int irq_num)
+{
+switch (irq_num) {
+case 0:
+return s->dev.config[0x55] >> 4;
+case 1:
+return s->dev.config[0x56] & 0xf;
+case 2:
+return s->dev.config[0x56] >> 4;
+case 3:
+return s->dev.config[0x57] >> 4;
+}
+return 0;
+}
+
+static void via_isa_set_pci_irq(void *opaque, int irq_num, int level)
+{
+ViaISAState *s = opaque;
+PCIBus *bus = pci_get_bus(&s->dev);
+int pic_irq;
+
+/* now we change the pic irq level according to the via irq mappings */
+/* XXX: optimize */
+pic_irq = via_isa_get_pci_irq(s, irq_num);
+if (pic_irq < ISA_NUM_IRQS) {


the ISA IRQ is stored in 4-bit so will always be in range.


+int i, pic_level;
+
+/* The pic level is the logical OR of all the PCI irqs mapped to it. */
+pic_level = 0;
+for (i = 0; i < PCI_NUM_PINS; i++) {
+if (pic_irq == via_isa_get_pci_irq(s, i)) {
+pic_level |= pci_bus_get_irq_level(bus, i);
+}
+}
+qemu_set_irq(s->isa_irqs[pic_irq], pic_level);
+}
+}






Re: [PATCH v3 4/8] hw/isa/vt82c686: Implement PCI IRQ routing

2023-02-26 Thread BALATON Zoltan

On Sun, 26 Feb 2023, Philippe Mathieu-Daudé wrote:

On 25/2/23 19:11, BALATON Zoltan wrote:

From: Bernhard Beschow 

The real VIA south bridges implement a PCI IRQ router which is configured
by the BIOS or the OS. In order to respect these configurations, QEMU
needs to implement it as well.

Note: The implementation was taken from piix4_set_irq() in hw/isa/piix4.

Signed-off-by: Bernhard Beschow 
[balaton: declare gpio inputs instead of changing pci bus irqs so it can
  be connected in board code; remove some empty lines]
Signed-off-by: BALATON Zoltan 
Tested-by: Rene Engel 
---
  hw/isa/vt82c686.c | 39 +++
  1 file changed, 39 insertions(+)



+static int via_isa_get_pci_irq(const ViaISAState *s, int irq_num)
+{
+switch (irq_num) {
+case 0:
+return s->dev.config[0x55] >> 4;
+case 1:
+return s->dev.config[0x56] & 0xf;
+case 2:
+return s->dev.config[0x56] >> 4;
+case 3:
+return s->dev.config[0x57] >> 4;
+}
+return 0;
+}
+
+static void via_isa_set_pci_irq(void *opaque, int irq_num, int level)
+{
+ViaISAState *s = opaque;
+PCIBus *bus = pci_get_bus(&s->dev);
+int pic_irq;
+
+/* now we change the pic irq level according to the via irq mappings 
*/

+/* XXX: optimize */
+pic_irq = via_isa_get_pci_irq(s, irq_num);
+if (pic_irq < ISA_NUM_IRQS) {


the ISA IRQ is stored in 4-bit so will always be in range.


Complain at hw/isa/piix4 I guess or clean this up together later :-) Or 
maybe Bernhard has an idea or patch for this coming up that's why he 
pushed this in here. In any case, since this is now the same as piix4 
either both or nothing for this and both would be out of scope for this 
series.


Regards,
BALATON Zoltan


+int i, pic_level;
+
+/* The pic level is the logical OR of all the PCI irqs mapped to 
it. */

+pic_level = 0;
+for (i = 0; i < PCI_NUM_PINS; i++) {
+if (pic_irq == via_isa_get_pci_irq(s, i)) {
+pic_level |= pci_bus_get_irq_level(bus, i);
+}
+}
+qemu_set_irq(s->isa_irqs[pic_irq], pic_level);
+}
+}






Re: [PATCH v3 5/8] hw/ppc/pegasos2: Fix PCI interrupt routing

2023-02-26 Thread Bernhard Beschow



Am 16. Februar 2023 20:27:32 UTC schrieb BALATON Zoltan :
>According to the PegasosII schematics the PCI interrupt lines are
>connected to both the gpp pins of the Mv64361 north bridge and the
>PINT pins of the VT8231 south bridge so guests can get interrupts from
>either of these. So far we only had the MV64361 connections which
>worked for on board devices but for additional PCI devices (such as
>network or sound card added with -device) guest OSes expect interrupt
>from the ISA IRQ 9 where the firmware routes these PCI interrupts in
>VT8231 ISA bridge. After the previous patches we can now model this
>and also remove the board specific connection from mv64361. Also
>configure routing of these lines when using Virtual Open Firmware to
>match board firmware for guests that expect this.
>
>This fixes PCI interrupts on pegasos2 under Linux, MorphOS and AmigaOS.
>
>Signed-off-by: BALATON Zoltan 
>Tested-by: Rene Engel 
>Reviewed-by: Daniel Henrique Barboza 
>---
> hw/pci-host/mv64361.c |  4 
> hw/ppc/pegasos2.c | 26 +-
> 2 files changed, 25 insertions(+), 5 deletions(-)
>
>diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c
>index f43f33fbd9..3d9132f989 100644
>--- a/hw/pci-host/mv64361.c
>+++ b/hw/pci-host/mv64361.c
>@@ -874,10 +874,6 @@ static void mv64361_realize(DeviceState *dev, Error 
>**errp)
> }
> sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq);
> qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32);
>-/* FIXME: PCI IRQ connections may be board specific */
>-for (i = 0; i < PCI_NUM_PINS; i++) {
>-s->pci[1].irq[i] = qdev_get_gpio_in_named(dev, "gpp", 12 + i);
>-}
> }
> 
> static void mv64361_reset(DeviceState *dev)
>diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
>index a9563f4fb2..4e1476673b 100644
>--- a/hw/ppc/pegasos2.c
>+++ b/hw/ppc/pegasos2.c
>@@ -74,6 +74,8 @@ struct Pegasos2MachineState {
> MachineState parent_obj;
> PowerPCCPU *cpu;
> DeviceState *mv;
>+qemu_irq mv_pirq[PCI_NUM_PINS];
>+qemu_irq via_pirq[PCI_NUM_PINS];
> Vof *vof;
> void *fdt_blob;
> uint64_t kernel_addr;
>@@ -96,6 +98,15 @@ static void pegasos2_cpu_reset(void *opaque)
> }
> }
> 
>+static void pegasos2_pci_irq(void *opaque, int n, int level)
>+{
>+Pegasos2MachineState *pm = opaque;
>+
>+/* PCI interrupt lines are connected to both MV64361 and VT8231 */
>+qemu_set_irq(pm->mv_pirq[n], level);
>+qemu_set_irq(pm->via_pirq[n], level);
>+}
>+
> static void pegasos2_init(MachineState *machine)
> {
> Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
>@@ -107,7 +118,7 @@ static void pegasos2_init(MachineState *machine)
> I2CBus *i2c_bus;
> const char *fwname = machine->firmware ?: PROM_FILENAME;
> char *filename;
>-int sz;
>+int i, sz;
> uint8_t *spd_data;
> 
> /* init CPU */
>@@ -157,11 +168,18 @@ static void pegasos2_init(MachineState *machine)
> /* Marvell Discovery II system controller */
> pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
>   qdev_get_gpio_in(DEVICE(pm->cpu), 
> PPC6xx_INPUT_INT)));
>+for (i = 0; i < PCI_NUM_PINS; i++) {
>+pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->mv, "gpp", 12 + i);
>+}
> pci_bus = mv64361_get_pci_bus(pm->mv, 1);
>+pci_bus_irqs(pci_bus, pegasos2_pci_irq, pm, PCI_NUM_PINS);
> 
> /* VIA VT8231 South Bridge (multifunction PCI device) */
> via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0),
>  true, TYPE_VT8231_ISA));
>+for (i = 0; i < PCI_NUM_PINS; i++) {
>+pm->via_pirq[i] = qdev_get_gpio_in_named(DEVICE(via), "pirq", i);
>+}
> object_property_add_alias(OBJECT(machine), "rtc-time",
>   object_resolve_path_component(via, "rtc"),
>   "date");
>@@ -268,6 +286,12 @@ static void pegasos2_machine_reset(MachineState *machine, 
>ShutdownCause reason)
>   PCI_INTERRUPT_LINE, 2, 0x9);
> pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>   0x50, 1, 0x2);
>+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>+  0x55, 1, 0x90);
>+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>+  0x56, 1, 0x99);
>+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>+  0x57, 1, 0x90);

Let's not mix aspects (implement VT82XX PCI IRQ routing) with Pegasos2 aspects. 
IOW let's keep these additions in a separate patch to make things clearer.

> 
> pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 1) << 8) |
>   PCI_INTERRUPT_LINE, 2, 0x109);



Re: [PATCH v3 4/8] hw/isa/vt82c686: Implement PCI IRQ routing

2023-02-26 Thread Bernhard Beschow



Am 25. Februar 2023 18:11:49 UTC schrieb BALATON Zoltan :
>From: Bernhard Beschow 
>
>The real VIA south bridges implement a PCI IRQ router which is configured
>by the BIOS or the OS. In order to respect these configurations, QEMU
>needs to implement it as well.
>
>Note: The implementation was taken from piix4_set_irq() in hw/isa/piix4.
>
>Signed-off-by: Bernhard Beschow 
>[balaton: declare gpio inputs instead of changing pci bus irqs so it can
> be connected in board code; remove some empty lines]
>Signed-off-by: BALATON Zoltan 
>Tested-by: Rene Engel 
>---
> hw/isa/vt82c686.c | 39 +++
> 1 file changed, 39 insertions(+)
>
>diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
>index 3f9bd0c04d..4025f9bcdc 100644
>--- a/hw/isa/vt82c686.c
>+++ b/hw/isa/vt82c686.c
>@@ -604,6 +604,44 @@ static void via_isa_request_i8259_irq(void *opaque, int 
>irq, int level)
> qemu_set_irq(s->cpu_intr, level);
> }
> 
>+static int via_isa_get_pci_irq(const ViaISAState *s, int irq_num)
>+{
>+switch (irq_num) {
>+case 0:
>+return s->dev.config[0x55] >> 4;
>+case 1:
>+return s->dev.config[0x56] & 0xf;
>+case 2:
>+return s->dev.config[0x56] >> 4;
>+case 3:
>+return s->dev.config[0x57] >> 4;
>+}
>+return 0;
>+}
>+
>+static void via_isa_set_pci_irq(void *opaque, int irq_num, int level)
>+{
>+ViaISAState *s = opaque;
>+PCIBus *bus = pci_get_bus(&s->dev);
>+int pic_irq;
>+
>+/* now we change the pic irq level according to the via irq mappings */
>+/* XXX: optimize */
>+pic_irq = via_isa_get_pci_irq(s, irq_num);
>+if (pic_irq < ISA_NUM_IRQS) {
>+int i, pic_level;
>+
>+/* The pic level is the logical OR of all the PCI irqs mapped to it. 
>*/
>+pic_level = 0;
>+for (i = 0; i < PCI_NUM_PINS; i++) {
>+if (pic_irq == via_isa_get_pci_irq(s, i)) {
>+pic_level |= pci_bus_get_irq_level(bus, i);
>+}
>+}
>+qemu_set_irq(s->isa_irqs[pic_irq], pic_level);
>+}
>+}
>+
> static void via_isa_realize(PCIDevice *d, Error **errp)
> {
> ViaISAState *s = VIA_ISA(d);
>@@ -614,6 +652,7 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
> int i;
> 
> qdev_init_gpio_out(dev, &s->cpu_intr, 1);
>+qdev_init_gpio_in_named(dev, via_isa_set_pci_irq, "pirq", PCI_NUM_PINS);

This line is a Pegasos2 specific addition for fixing its IRQ handling. Since 
this code must also work with the Fuloong2e board we should aim for a minimal 
changeset here which renders this line out of scope.

Let's keep the two series separate since now I need to watch two series for 
comments. Please use Based-on: tag next time instead.

Thanks,
Bernhard

> isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
> isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d),
>   errp);



Re: [PATCH v3 4/8] hw/isa/vt82c686: Implement PCI IRQ routing

2023-02-26 Thread Bernhard Beschow



Am 26. Februar 2023 22:27:50 UTC schrieb "Philippe Mathieu-Daudé" 
:
>On 25/2/23 19:11, BALATON Zoltan wrote:
>> From: Bernhard Beschow 
>> 
>> The real VIA south bridges implement a PCI IRQ router which is configured
>> by the BIOS or the OS. In order to respect these configurations, QEMU
>> needs to implement it as well.
>> 
>> Note: The implementation was taken from piix4_set_irq() in hw/isa/piix4.
>> 
>> Signed-off-by: Bernhard Beschow 
>> [balaton: declare gpio inputs instead of changing pci bus irqs so it can
>>   be connected in board code; remove some empty lines]
>> Signed-off-by: BALATON Zoltan 
>> Tested-by: Rene Engel 
>> ---
>>   hw/isa/vt82c686.c | 39 +++
>>   1 file changed, 39 insertions(+)
>
>> +static int via_isa_get_pci_irq(const ViaISAState *s, int irq_num)
>> +{
>> +switch (irq_num) {
>> +case 0:
>> +return s->dev.config[0x55] >> 4;
>> +case 1:
>> +return s->dev.config[0x56] & 0xf;
>> +case 2:
>> +return s->dev.config[0x56] >> 4;
>> +case 3:
>> +return s->dev.config[0x57] >> 4;
>> +}
>> +return 0;
>> +}
>> +
>> +static void via_isa_set_pci_irq(void *opaque, int irq_num, int level)
>> +{
>> +ViaISAState *s = opaque;
>> +PCIBus *bus = pci_get_bus(&s->dev);
>> +int pic_irq;
>> +
>> +/* now we change the pic irq level according to the via irq mappings */
>> +/* XXX: optimize */
>> +pic_irq = via_isa_get_pci_irq(s, irq_num);
>> +if (pic_irq < ISA_NUM_IRQS) {
>
>the ISA IRQ is stored in 4-bit so will always be in range.

Indeed. I'd turn this into an assert to keep this assum visible. I'll do 
another iteration of the PCI IRQ router series.

Best regards,
Bernhard
>
>> +int i, pic_level;
>> +
>> +/* The pic level is the logical OR of all the PCI irqs mapped to 
>> it. */
>> +pic_level = 0;
>> +for (i = 0; i < PCI_NUM_PINS; i++) {
>> +if (pic_irq == via_isa_get_pci_irq(s, i)) {
>> +pic_level |= pci_bus_get_irq_level(bus, i);
>> +}
>> +}
>> +qemu_set_irq(s->isa_irqs[pic_irq], pic_level);
>> +}
>> +}
>
>



Re: [PATCH v3 4/8] hw/isa/vt82c686: Implement PCI IRQ routing

2023-02-26 Thread BALATON Zoltan

On Sun, 26 Feb 2023, Bernhard Beschow wrote:

Am 25. Februar 2023 18:11:49 UTC schrieb BALATON Zoltan :

From: Bernhard Beschow 

The real VIA south bridges implement a PCI IRQ router which is configured
by the BIOS or the OS. In order to respect these configurations, QEMU
needs to implement it as well.

Note: The implementation was taken from piix4_set_irq() in hw/isa/piix4.

Signed-off-by: Bernhard Beschow 
[balaton: declare gpio inputs instead of changing pci bus irqs so it can
be connected in board code; remove some empty lines]
Signed-off-by: BALATON Zoltan 
Tested-by: Rene Engel 
---
hw/isa/vt82c686.c | 39 +++
1 file changed, 39 insertions(+)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 3f9bd0c04d..4025f9bcdc 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -604,6 +604,44 @@ static void via_isa_request_i8259_irq(void *opaque, int 
irq, int level)
qemu_set_irq(s->cpu_intr, level);
}

+static int via_isa_get_pci_irq(const ViaISAState *s, int irq_num)
+{
+switch (irq_num) {
+case 0:
+return s->dev.config[0x55] >> 4;
+case 1:
+return s->dev.config[0x56] & 0xf;
+case 2:
+return s->dev.config[0x56] >> 4;
+case 3:
+return s->dev.config[0x57] >> 4;
+}
+return 0;
+}
+
+static void via_isa_set_pci_irq(void *opaque, int irq_num, int level)
+{
+ViaISAState *s = opaque;
+PCIBus *bus = pci_get_bus(&s->dev);
+int pic_irq;
+
+/* now we change the pic irq level according to the via irq mappings */
+/* XXX: optimize */
+pic_irq = via_isa_get_pci_irq(s, irq_num);
+if (pic_irq < ISA_NUM_IRQS) {
+int i, pic_level;
+
+/* The pic level is the logical OR of all the PCI irqs mapped to it. */
+pic_level = 0;
+for (i = 0; i < PCI_NUM_PINS; i++) {
+if (pic_irq == via_isa_get_pci_irq(s, i)) {
+pic_level |= pci_bus_get_irq_level(bus, i);
+}
+}
+qemu_set_irq(s->isa_irqs[pic_irq], pic_level);
+}
+}
+
static void via_isa_realize(PCIDevice *d, Error **errp)
{
ViaISAState *s = VIA_ISA(d);
@@ -614,6 +652,7 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
int i;

qdev_init_gpio_out(dev, &s->cpu_intr, 1);
+qdev_init_gpio_in_named(dev, via_isa_set_pci_irq, "pirq", PCI_NUM_PINS);


This line is a Pegasos2 specific addition for fixing its IRQ handling. Since 
this code must also work with the Fuloong2e board we should aim for a minimal 
changeset here which renders this line out of scope.

Let's keep the two series separate since now I need to watch two series for 
comments. Please use Based-on: tag next time instead.


Well, it's not. It's part of the QDev model for VT8231 that allows it to 
be connected by boards so I think this belongs here otherwise this won't 
even compile because the function you've added would be unused and bail on 
-Werror. Let's not make this more difficult than it is. I'm OK with 
reasonable changes but what's your goal now? You can't get rid of this 
line as it's how QDev can model it. Either I have to call into this model 
or have to export these pins as gpios.


Regards,
BALATON Zoltan


Thanks,
Bernhard


isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d),
  errp);







Re: [PATCH v3 4/8] hw/isa/vt82c686: Implement PCI IRQ routing

2023-02-26 Thread BALATON Zoltan

On Sun, 26 Feb 2023, Bernhard Beschow wrote:

Am 26. Februar 2023 22:27:50 UTC schrieb "Philippe Mathieu-Daudé" 
:

On 25/2/23 19:11, BALATON Zoltan wrote:

From: Bernhard Beschow 

The real VIA south bridges implement a PCI IRQ router which is configured
by the BIOS or the OS. In order to respect these configurations, QEMU
needs to implement it as well.

Note: The implementation was taken from piix4_set_irq() in hw/isa/piix4.

Signed-off-by: Bernhard Beschow 
[balaton: declare gpio inputs instead of changing pci bus irqs so it can
  be connected in board code; remove some empty lines]
Signed-off-by: BALATON Zoltan 
Tested-by: Rene Engel 
---
  hw/isa/vt82c686.c | 39 +++
  1 file changed, 39 insertions(+)



+static int via_isa_get_pci_irq(const ViaISAState *s, int irq_num)
+{
+switch (irq_num) {
+case 0:
+return s->dev.config[0x55] >> 4;
+case 1:
+return s->dev.config[0x56] & 0xf;
+case 2:
+return s->dev.config[0x56] >> 4;
+case 3:
+return s->dev.config[0x57] >> 4;
+}
+return 0;
+}
+
+static void via_isa_set_pci_irq(void *opaque, int irq_num, int level)
+{
+ViaISAState *s = opaque;
+PCIBus *bus = pci_get_bus(&s->dev);
+int pic_irq;
+
+/* now we change the pic irq level according to the via irq mappings */
+/* XXX: optimize */
+pic_irq = via_isa_get_pci_irq(s, irq_num);
+if (pic_irq < ISA_NUM_IRQS) {


the ISA IRQ is stored in 4-bit so will always be in range.


Indeed. I'd turn this into an assert to keep this assum visible. I'll do 
another iteration of the PCI IRQ router series.


If you do that please don't break it and make me redo this series again. 
Sumbit a patch as a reply to this that can be substituted without changing 
other patches and I can include in later respins. We don't have time to 
make extensive changes now, the freeze is too close.


Regards,
BALATON Zoltan


Best regards,
Bernhard



+int i, pic_level;
+
+/* The pic level is the logical OR of all the PCI irqs mapped to it. */
+pic_level = 0;
+for (i = 0; i < PCI_NUM_PINS; i++) {
+if (pic_irq == via_isa_get_pci_irq(s, i)) {
+pic_level |= pci_bus_get_irq_level(bus, i);
+}
+}
+qemu_set_irq(s->isa_irqs[pic_irq], pic_level);
+}
+}







Re: [PATCH v3 5/8] hw/ppc/pegasos2: Fix PCI interrupt routing

2023-02-26 Thread BALATON Zoltan

On Sun, 26 Feb 2023, Bernhard Beschow wrote:

Am 16. Februar 2023 20:27:32 UTC schrieb BALATON Zoltan :

According to the PegasosII schematics the PCI interrupt lines are
connected to both the gpp pins of the Mv64361 north bridge and the
PINT pins of the VT8231 south bridge so guests can get interrupts from
either of these. So far we only had the MV64361 connections which
worked for on board devices but for additional PCI devices (such as
network or sound card added with -device) guest OSes expect interrupt
from the ISA IRQ 9 where the firmware routes these PCI interrupts in
VT8231 ISA bridge. After the previous patches we can now model this
and also remove the board specific connection from mv64361. Also
configure routing of these lines when using Virtual Open Firmware to
match board firmware for guests that expect this.

This fixes PCI interrupts on pegasos2 under Linux, MorphOS and AmigaOS.

Signed-off-by: BALATON Zoltan 
Tested-by: Rene Engel 
Reviewed-by: Daniel Henrique Barboza 
---
hw/pci-host/mv64361.c |  4 
hw/ppc/pegasos2.c | 26 +-
2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c
index f43f33fbd9..3d9132f989 100644
--- a/hw/pci-host/mv64361.c
+++ b/hw/pci-host/mv64361.c
@@ -874,10 +874,6 @@ static void mv64361_realize(DeviceState *dev, Error **errp)
}
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq);
qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32);
-/* FIXME: PCI IRQ connections may be board specific */
-for (i = 0; i < PCI_NUM_PINS; i++) {
-s->pci[1].irq[i] = qdev_get_gpio_in_named(dev, "gpp", 12 + i);
-}
}

static void mv64361_reset(DeviceState *dev)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index a9563f4fb2..4e1476673b 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -74,6 +74,8 @@ struct Pegasos2MachineState {
MachineState parent_obj;
PowerPCCPU *cpu;
DeviceState *mv;
+qemu_irq mv_pirq[PCI_NUM_PINS];
+qemu_irq via_pirq[PCI_NUM_PINS];
Vof *vof;
void *fdt_blob;
uint64_t kernel_addr;
@@ -96,6 +98,15 @@ static void pegasos2_cpu_reset(void *opaque)
}
}

+static void pegasos2_pci_irq(void *opaque, int n, int level)
+{
+Pegasos2MachineState *pm = opaque;
+
+/* PCI interrupt lines are connected to both MV64361 and VT8231 */
+qemu_set_irq(pm->mv_pirq[n], level);
+qemu_set_irq(pm->via_pirq[n], level);
+}
+
static void pegasos2_init(MachineState *machine)
{
Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
@@ -107,7 +118,7 @@ static void pegasos2_init(MachineState *machine)
I2CBus *i2c_bus;
const char *fwname = machine->firmware ?: PROM_FILENAME;
char *filename;
-int sz;
+int i, sz;
uint8_t *spd_data;

/* init CPU */
@@ -157,11 +168,18 @@ static void pegasos2_init(MachineState *machine)
/* Marvell Discovery II system controller */
pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
  qdev_get_gpio_in(DEVICE(pm->cpu), PPC6xx_INPUT_INT)));
+for (i = 0; i < PCI_NUM_PINS; i++) {
+pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->mv, "gpp", 12 + i);
+}
pci_bus = mv64361_get_pci_bus(pm->mv, 1);
+pci_bus_irqs(pci_bus, pegasos2_pci_irq, pm, PCI_NUM_PINS);

/* VIA VT8231 South Bridge (multifunction PCI device) */
via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0),
 true, TYPE_VT8231_ISA));
+for (i = 0; i < PCI_NUM_PINS; i++) {
+pm->via_pirq[i] = qdev_get_gpio_in_named(DEVICE(via), "pirq", i);
+}
object_property_add_alias(OBJECT(machine), "rtc-time",
  object_resolve_path_component(via, "rtc"),
  "date");
@@ -268,6 +286,12 @@ static void pegasos2_machine_reset(MachineState *machine, 
ShutdownCause reason)
  PCI_INTERRUPT_LINE, 2, 0x9);
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
  0x50, 1, 0x2);
+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+  0x55, 1, 0x90);
+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+  0x56, 1, 0x99);
+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+  0x57, 1, 0x90);


Let's not mix aspects (implement VT82XX PCI IRQ routing) with Pegasos2 aspects. 
IOW let's keep these additions in a separate patch to make things clearer.


I guess this one hunk could be split out but not sure what would that 
bring.


Regards,
BALATON Zoltan



pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 1) << 8) |
  PCI_INTERRUPT_LINE, 2, 0x109);







Re: [PATCH v3 4/8] hw/isa/vt82c686: Implement PCI IRQ routing

2023-02-26 Thread BALATON Zoltan

On Sun, 26 Feb 2023, Bernhard Beschow wrote:

Am 26. Februar 2023 22:27:50 UTC schrieb "Philippe Mathieu-Daudé" 
:

On 25/2/23 19:11, BALATON Zoltan wrote:

From: Bernhard Beschow 

The real VIA south bridges implement a PCI IRQ router which is configured
by the BIOS or the OS. In order to respect these configurations, QEMU
needs to implement it as well.

Note: The implementation was taken from piix4_set_irq() in hw/isa/piix4.

Signed-off-by: Bernhard Beschow 
[balaton: declare gpio inputs instead of changing pci bus irqs so it can
  be connected in board code; remove some empty lines]
Signed-off-by: BALATON Zoltan 
Tested-by: Rene Engel 
---
  hw/isa/vt82c686.c | 39 +++
  1 file changed, 39 insertions(+)



+static int via_isa_get_pci_irq(const ViaISAState *s, int irq_num)
+{
+switch (irq_num) {
+case 0:
+return s->dev.config[0x55] >> 4;
+case 1:
+return s->dev.config[0x56] & 0xf;
+case 2:
+return s->dev.config[0x56] >> 4;
+case 3:
+return s->dev.config[0x57] >> 4;
+}
+return 0;
+}
+
+static void via_isa_set_pci_irq(void *opaque, int irq_num, int level)
+{
+ViaISAState *s = opaque;
+PCIBus *bus = pci_get_bus(&s->dev);
+int pic_irq;
+
+/* now we change the pic irq level according to the via irq mappings */
+/* XXX: optimize */
+pic_irq = via_isa_get_pci_irq(s, irq_num);
+if (pic_irq < ISA_NUM_IRQS) {


the ISA IRQ is stored in 4-bit so will always be in range.


Indeed. I'd turn this into an assert to keep this assum visible. I'll do 
another iteration of the PCI IRQ router series.


I don't like a useless assert in an irq handler that's potentially called 
a lot. If you want to keep that add a comment instead.


Also I can't use Based-on because having all patches in a single series 
helps maintainers to follow what belongs to here so this should be one 
series. You don't have to follow your one any more as it was fully 
incorporated here so this is the only version you'd have to watch.


Regards,
BALATON Zoltan


Best regards,
Bernhard



+int i, pic_level;
+
+/* The pic level is the logical OR of all the PCI irqs mapped to it. */
+pic_level = 0;
+for (i = 0; i < PCI_NUM_PINS; i++) {
+if (pic_irq == via_isa_get_pci_irq(s, i)) {
+pic_level |= pci_bus_get_irq_level(bus, i);
+}
+}
+qemu_set_irq(s->isa_irqs[pic_irq], pic_level);
+}
+}







Re: [PATCH 2/2] target/riscv/vector_helper.c: avoid env_archcpu() when reading RISCVCPUConfig

2023-02-26 Thread liweiwei



On 2023/2/27 01:05, Daniel Henrique Barboza wrote:

This file has several uses of env_archcpu() that are used solely to read
cfg->vlen. Use the new riscv_cpu_cfg() inline instead.

Suggested-by: Weiwei Li 
Signed-off-by: Daniel Henrique Barboza 



Reviewed-by: Weiwei Li

Weiwei Li


---
  target/riscv/vector_helper.c | 20 ++--
  1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 7d2e3978f1..a7fb09efa3 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -272,7 +272,7 @@ static void vext_set_tail_elems_1s(CPURISCVState *env, 
target_ulong vl,
 uint32_t esz, uint32_t max_elems)
  {
  uint32_t total_elems = vext_get_total_elems(env, desc, esz);
-uint32_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
+uint32_t vlenb = riscv_cpu_cfg(env)->vlen >> 3;
  uint32_t vta = vext_vta(desc);
  uint32_t registers_used;
  int k;
@@ -671,7 +671,7 @@ vext_ldst_whole(void *vd, target_ulong base, CPURISCVState 
*env, uint32_t desc,
  {
  uint32_t i, k, off, pos;
  uint32_t nf = vext_nf(desc);
-uint32_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
+uint32_t vlenb = riscv_cpu_cfg(env)->vlen >> 3;
  uint32_t max_elems = vlenb >> log2_esz;
  
  k = env->vstart / max_elems;

@@ -1141,7 +1141,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
  { \
  uint32_t vl = env->vl;\
  uint32_t vm = vext_vm(desc);  \
-uint32_t total_elems = env_archcpu(env)->cfg.vlen;\
+uint32_t total_elems = riscv_cpu_cfg(env)->vlen;  \
  uint32_t vta_all_1s = vext_vta_all_1s(desc);  \
  uint32_t i;   \
\
@@ -1177,7 +1177,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1,
  \
  {   \
  uint32_t vl = env->vl;  \
  uint32_t vm = vext_vm(desc);\
-uint32_t total_elems = env_archcpu(env)->cfg.vlen;  \
+uint32_t total_elems = riscv_cpu_cfg(env)->vlen;\
  uint32_t vta_all_1s = vext_vta_all_1s(desc);\
  uint32_t i; \
  \
@@ -1376,7 +1376,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
  { \
  uint32_t vm = vext_vm(desc);  \
  uint32_t vl = env->vl;\
-uint32_t total_elems = env_archcpu(env)->cfg.vlen;\
+uint32_t total_elems = riscv_cpu_cfg(env)->vlen;  \
  uint32_t vta_all_1s = vext_vta_all_1s(desc);  \
  uint32_t vma = vext_vma(desc);\
  uint32_t i;   \
@@ -1439,7 +1439,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2,   \
  {   \
  uint32_t vm = vext_vm(desc);\
  uint32_t vl = env->vl;  \
-uint32_t total_elems = env_archcpu(env)->cfg.vlen;  \
+uint32_t total_elems = riscv_cpu_cfg(env)->vlen;\
  uint32_t vta_all_1s = vext_vta_all_1s(desc);\
  uint32_t vma = vext_vma(desc);  \
  uint32_t i; \
@@ -4152,7 +4152,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
  { \
  uint32_t vm = vext_vm(desc);  \
  uint32_t vl = env->vl;\
-uint32_t total_elems = env_archcpu(env)->cfg.vlen;\
+uint32_t total_elems = riscv_cpu_cfg(env)->vlen;  \
  uint32_t vta_all_1s = vext_vta_all_1s(desc);  \
  uint32_t vma = vext_vma(desc);\
  uint32_t i;   \
@@ -4190,7 +4190,7 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void 
*vs2,   \
  {   \
  uint32_t vm = vext_vm(desc);\
  uint32_t vl = env->vl;  \
-uint32_t total_elems = env_archcpu(env)->cfg.vlen;  \
+uint32_t total_elems = riscv_cpu_cfg(env)->vlen;\
  uint32_t vta_all_1s = vext_vta_all_1

Reply: [PATCH] virtio-balloon: optimize the virtio-balloon on the ARM platform.

2023-02-26 Thread Yangming via



> On Fri, Feb 24, 2023 at 08:23:40AM +, Yangming wrote:
> >
> > Optimize the virtio-balloon feature on the ARM platform by adding a
> variable to keep track of the current hot-plugged pc-dimm size, instead of
> traversing the virtual machine's memory modules to count the current RAM
> size during the balloon inflation or deflation process. This variable can be
> updated only when plugging or unplugging the device, which will result in an
> increase of more than 60% efficiency of balloon process on the ARM platform.
> >
> > Signed-off-by: Qi Xi 
> > Signed-off-by: Ming Yang yangmin...@huawei.com
> 
> What kind of performance gains are achieved by this patch?
> Pls include some measurements: before and after.
> 
> 
> > ---
> >  hw/mem/pc-dimm.c   |  2 ++
> >  hw/virtio/virtio-balloon.c | 44 +-
> >  include/hw/boards.h|  1 +
> >  3 files changed, 18 insertions(+), 29 deletions(-)
> >
> > diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index
> 50ef83215c..192fc7922c 100644
> > --- a/hw/mem/pc-dimm.c
> > +++ b/hw/mem/pc-dimm.c
> > @@ -81,6 +81,7 @@ void pc_dimm_plug(PCDIMMDevice *dimm,
> MachineState *machine)
> >
> >  memory_device_plug(MEMORY_DEVICE(dimm), machine);
> >  vmstate_register_ram(vmstate_mr, DEVICE(dimm));
> > +machine->device_memory->dimm_size += vmstate_mr->size;
> >  }
> >
> >  void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine)
> @@ -90,6 +91,7 @@ void pc_dimm_unplug(PCDIMMDevice *dimm,
> MachineState *machine)
> >
> >  memory_device_unplug(MEMORY_DEVICE(dimm), machine);
> >  vmstate_unregister_ram(vmstate_mr, DEVICE(dimm));
> > +machine->device_memory->dimm_size -= vmstate_mr->size;
> >  }
> >
> >  static int pc_dimm_slot2bitmap(Object *obj, void *opaque) diff --git
> a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index
> 746f07c4d2..40fa40109d 100644
> > --- a/hw/virtio/virtio-balloon.c
> > +++ b/hw/virtio/virtio-balloon.c
> > @@ -729,37 +729,14 @@ static void virtio_balloon_get_config(VirtIODevice
> *vdev, uint8_t *config_data)
> >  memcpy(config_data, &config, virtio_balloon_config_size(dev));  }
> >
> > -static int build_dimm_list(Object *obj, void *opaque) -{
> > -GSList **list = opaque;
> > -
> > -if (object_dynamic_cast(obj, TYPE_PC_DIMM)) {
> > -DeviceState *dev = DEVICE(obj);
> > -if (dev->realized) { /* only realized DIMMs matter */
> > -*list = g_slist_prepend(*list, dev);
> > -}
> > -}
> > -
> > -object_child_foreach(obj, build_dimm_list, opaque);
> > -return 0;
> > -}
> > -
> >  static ram_addr_t get_current_ram_size(void)  {
> > -GSList *list = NULL, *item;
> > -ram_addr_t size = current_machine->ram_size;
> > -
> > -build_dimm_list(qdev_get_machine(), &list);
> > -for (item = list; item; item = g_slist_next(item)) {
> > -Object *obj = OBJECT(item->data);
> > -if (!strcmp(object_get_typename(obj), TYPE_PC_DIMM)) {
> > -size += object_property_get_int(obj, PC_DIMM_SIZE_PROP,
> > -&error_abort);
> > -}
> > +MachineState *machine = MACHINE(qdev_get_machine());
> > +if (machine->device_memory != NULL) {
> > +return machine->ram_size + machine->device_memory->dimm_size;
> > +} else {
> > +return machine->ram_size;
> >  }
> > -g_slist_free(list);
> > -
> > -return size;
> >  }
> >
> >  static bool virtio_balloon_page_poison_support(void *opaque) @@ -776,7
> +753,11 @@ static void virtio_balloon_set_config(VirtIODevice *vdev,
> >  VirtIOBalloon *dev = VIRTIO_BALLOON(vdev);
> >  struct virtio_balloon_config config;
> >  uint32_t oldactual = dev->actual;
> > -ram_addr_t vm_ram_size = get_current_ram_size();
> > +ram_addr_t vm_ram_size;
> > +ram_addr_t vm_ram_size_new;
> > +
> > +retry:
> > +vm_ram_size = get_current_ram_size();
> >
> >  memcpy(&config, config_data, virtio_balloon_config_size(dev));
> >  dev->actual = le32_to_cpu(config.actual); @@ -784,6 +765,11 @@ static
> void virtio_balloon_set_config(VirtIODevice *vdev,
> >  qapi_event_send_balloon_change(vm_ram_size -
> >  ((ram_addr_t) dev->actual << 
> > VIRTIO_BALLOON_PFN_SHIFT));
> >  }
> > +vm_ram_size_new = get_current_ram_size();
> > +if (vm_ram_size_new != vm_ram_size) {
> > +goto retry;
> > +}
> > +
> 
> What is this doing? needs and comment.
> And please don't implement loops using goto.
> 
> 
> >  dev->poison_val = 0;
> >  if (virtio_balloon_page_poison_support(dev)) {
> >  dev->poison_val = le32_to_cpu(config.poison_val); diff --git
> a/include/hw/boards.h b/include/hw/boards.h index
> 6fbbfd56c8..551b4b419e 100644
> > --- a/include/hw/boards.h
> > +++ b/include/hw/boards.h
> > @@ -296,6 +296,7 @@ struct MachineClass {  typedef struct
> DeviceMemoryState {
> >  hwaddr base;
> >  MemoryRegion mr;
> > +ram_ad

Re: [PATCH 74/76] tracing: remove transform.py

2023-02-26 Thread gaosong



在 2023/2/26 上午2:38, Richard Henderson 写道:

On 2/25/23 00:22, Daniel Henrique Barboza wrote:

Richard,

Not sure if I forgot or missed something but this patch breaks my 
build as follows:


$  make -j
   GIT ui/keycodemapdb tests/fp/berkeley-testfloat-3 
tests/fp/berkeley-softfloat-3 dtc

[1/885] Generating trace/trace-hw_hyperv.c with a custom command
FAILED: trace/trace-hw_hyperv.c
/usr/bin/python3 ../scripts/tracetool.py --backend=log 
--group=hw_hyperv --format=c 
/home/danielhb/work/qemu/hw/hyperv/trace-events trace/trace-hw_hyperv.c

Traceback (most recent call last):
   File "/home/danielhb/work/qemu/build/../scripts/tracetool.py", 
line 19, in 

 from tracetool import error_write, out, out_open
   File "/home/danielhb/work/qemu/scripts/tracetool/__init__.py", 
line 21, in 

 import tracetool.transform
ModuleNotFoundError: No module named 'tracetool.transform'



I saw the same thing on gitlab, but not on my laptop.  Weird.


I always get this things.


[26/2330] Generating trace/trace-hw_block.h with a custom command
FAILED: trace/trace-hw_block.h
/usr/bin/python3 ../scripts/tracetool.py --backend=log --group=hw_block 
--format=h /root/qemu/hw/block/trace-events trace/trace-hw_block.h

Traceback (most recent call last):
  File "/root/qemu/build/../scripts/tracetool.py", line 19, in 
    from tracetool import error_write, out, out_open
  File "/root/qemu/scripts/tracetool/__init__.py", line 21, in 
    import tracetool.transform
ModuleNotFoundError: No module named 'tracetool.transform'

It seems that tracetool.py is still referring transform. This fixes 
the build

for me:

$ git diff
diff --git a/scripts/tracetool/__init__.py 
b/scripts/tracetool/__init__.py

index 5393c7fc5c..c361815bc1 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -18,7 +18,6 @@

  import tracetool.format
  import tracetool.backend
-import tracetool.transform


I also removed some code below that used these symbols; they 
themselves appear to be unused.



r~





Re: [PATCH] hw/riscv: Skip re-generating DT nodes for a given DTB

2023-02-26 Thread Bin Meng
On Tue, Feb 21, 2023 at 7:32 PM Daniel Henrique Barboza
 wrote:
>
>
>
> On 2/21/23 03:12, Bin Meng wrote:
> > Lanuch qemu-system-riscv64 with a given dtb for 'sifive_u' and 'virt'
> > machines, QEMU complains:
> >
> >qemu_fdt_add_subnode: Failed to create subnode /soc: FDT_ERR_EXISTS
> >
> > The whole DT generation logic should be skipped when a given DTB is
> > present.
> >
> > Fixes: b1f19f238cae ("hw/riscv: write bootargs 'chosen' FDT after 
> > riscv_load_kernel()")
>
> Thanks for cleaning my mess :)
>
> I was wondering whether we should move the ms->dtb verification/load bits 
> outside of
> create_fdt(), and put it explicitly in sifive_u_machine_init() and 
> virt_machine_init().
> Like this:
>
>  /* load/create device tree*/
>  if (ms->dtb) {
>  ms->fdt = d(ms->dtb, &s->fdt_size);
>  if (!ms->fdt) {
>  error_report("load_device_tree() failed");
>  exit(1);
>  }
>  } else {
>  create_fdt(s, memmap);
>  }
>
>
> This looks clearer to me because create_fdt() will actually create a fdt, not 
> load or create
> a fdt. create_fdt() from spike works this way.

Yes, this makes sense.

>
> I'll leave to your discretion. The patch is already good enough as is.
>

I think we can create another patch to do the move as you suggested.
Because this patch we use a "Fixes" tag to refer to the culprit
commit, and this patch just does the minimum thing to fix that.

>
> Reviewed-by: Daniel Henrique Barboza 
>
> > Signed-off-by: Bin Meng 
> > ---
> >
> >   hw/riscv/sifive_u.c | 1 +
> >   hw/riscv/virt.c | 1 +
> >   2 files changed, 2 insertions(+)
> >
> > diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> > index ad3bb35b34..76db5ed3dd 100644
> > --- a/hw/riscv/sifive_u.c
> > +++ b/hw/riscv/sifive_u.c
> > @@ -118,6 +118,7 @@ static void create_fdt(SiFiveUState *s, const 
> > MemMapEntry *memmap,
> >   error_report("load_device_tree() failed");
> >   exit(1);
> >   }
> > +return;
> >   } else {
> >   fdt = ms->fdt = create_device_tree(&fdt_size);
> >   if (!fdt) {
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index 86c4adc0c9..0c7b4a1e46 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -1014,6 +1014,7 @@ static void create_fdt(RISCVVirtState *s, const 
> > MemMapEntry *memmap)
> >   error_report("load_device_tree() failed");
> >   exit(1);
> >   }
> > +return;
> >   } else {
> >   ms->fdt = create_device_tree(&s->fdt_size);
> >   if (!ms->fdt) {
>

Regards,
Bin



Re: [PATCH 1/2] gitlab/opensbi: Move to docker:stable

2023-02-26 Thread Bin Meng
On Sat, Feb 25, 2023 at 5:26 AM Palmer Dabbelt  wrote:
>
> The OpenSBI build has been using docker:19.03.1, which appears to be old
> enough that v2 of the manifest is no longer supported.  Something has
> started serving us those manifests, resulting in errors along the lines
> of
>
> $ docker build --cache-from $IMAGE_TAG --tag 
> $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $IMAGE_TAG .gitlab-ci.d/opensbi
> Step 1/7 : FROM ubuntu:18.04
> 18.04: Pulling from library/ubuntu
> mediaType in manifest should be 
> 'application/vnd.docker.distribution.manifest.v2+json' not 
> 'application/vnd.oci.image.manifest.v1+json'
>
> This just moves to docker:stable, as was suggested by the template.
>
> Signed-off-by: Palmer Dabbelt 
> ---
>  .gitlab-ci.d/opensbi.yml | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>

Thanks Palmer for looking into this!

Reviewed-by: Bin Meng 



Re: [PATCH 31/76] target/loongarch: Drop temp_new

2023-02-26 Thread gaosong



在 2023/2/25 下午5:13, Richard Henderson 写道:

Translators are no longer required to free tcg temporaries,
therefore there's no need to record temps for later freeing.
Replace the few uses with tcg_temp_new.

Signed-off-by: Richard Henderson 
---
  target/loongarch/translate.h  |  3 ---
  target/loongarch/translate.c  | 21 +++
  .../insn_trans/trans_privileged.c.inc |  2 +-
  3 files changed, 4 insertions(+), 22 deletions(-)

Reviewed-by: Song Gao 

Thanks.
Song Gao

diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
index 6d2e382e8b..67bc74c05b 100644
--- a/target/loongarch/translate.h
+++ b/target/loongarch/translate.h
@@ -32,9 +32,6 @@ typedef struct DisasContext {
  uint16_t mem_idx;
  uint16_t plv;
  TCGv zero;
-/* Space for 3 operands plus 1 extra for address computation. */
-TCGv temp[4];
-uint8_t ntemp;
  } DisasContext;
  
  void generate_exception(DisasContext *ctx, int excp);

diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 2a43ab0201..f443b5822f 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -85,9 +85,6 @@ static void loongarch_tr_init_disas_context(DisasContextBase 
*dcbase,
  bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
  ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
  
-ctx->ntemp = 0;

-memset(ctx->temp, 0, sizeof(ctx->temp));
-
  ctx->zero = tcg_constant_tl(0);
  }
  
@@ -110,12 +107,6 @@ static void loongarch_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)

   *
   * Further, we may provide an extension for word operations.
   */
-static TCGv temp_new(DisasContext *ctx)
-{
-assert(ctx->ntemp < ARRAY_SIZE(ctx->temp));
-return ctx->temp[ctx->ntemp++] = tcg_temp_new();
-}
-
  static TCGv gpr_src(DisasContext *ctx, int reg_num, DisasExtend src_ext)
  {
  TCGv t;
@@ -128,11 +119,11 @@ static TCGv gpr_src(DisasContext *ctx, int reg_num, 
DisasExtend src_ext)
  case EXT_NONE:
  return cpu_gpr[reg_num];
  case EXT_SIGN:
-t = temp_new(ctx);
+t = tcg_temp_new();
  tcg_gen_ext32s_tl(t, cpu_gpr[reg_num]);
  return t;
  case EXT_ZERO:
-t = temp_new(ctx);
+t = tcg_temp_new();
  tcg_gen_ext32u_tl(t, cpu_gpr[reg_num]);
  return t;
  }
@@ -142,7 +133,7 @@ static TCGv gpr_src(DisasContext *ctx, int reg_num, 
DisasExtend src_ext)
  static TCGv gpr_dst(DisasContext *ctx, int reg_num, DisasExtend dst_ext)
  {
  if (reg_num == 0 || dst_ext) {
-return temp_new(ctx);
+return tcg_temp_new();
  }
  return cpu_gpr[reg_num];
  }
@@ -195,12 +186,6 @@ static void loongarch_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cs)
  generate_exception(ctx, EXCCODE_INE);
  }
  
-for (int i = ctx->ntemp - 1; i >= 0; --i) {

-tcg_temp_free(ctx->temp[i]);
-ctx->temp[i] = NULL;
-}
-ctx->ntemp = 0;
-
  ctx->base.pc_next += 4;
  }
  
diff --git a/target/loongarch/insn_trans/trans_privileged.c.inc b/target/loongarch/insn_trans/trans_privileged.c.inc

index 40f82becb0..56f4c45e09 100644
--- a/target/loongarch/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/insn_trans/trans_privileged.c.inc
@@ -243,7 +243,7 @@ static bool trans_csrwr(DisasContext *ctx, arg_csrwr *a)
  dest = gpr_dst(ctx, a->rd, EXT_NONE);
  csr->writefn(dest, cpu_env, src1);
  } else {
-dest = temp_new(ctx);
+dest = tcg_temp_new();
  tcg_gen_ld_tl(dest, cpu_env, csr->offset);
  tcg_gen_st_tl(src1, cpu_env, csr->offset);
  }





Re: [PATCH 32/76] target/loongarch: Drop tcg_temp_free

2023-02-26 Thread gaosong



在 2023/2/25 下午5:13, Richard Henderson 写道:

Translators are no longer required to free tcg temporaries.

Signed-off-by: Richard Henderson 
---
  target/loongarch/insn_trans/trans_arith.c.inc | 12 ---
  .../loongarch/insn_trans/trans_atomic.c.inc   |  3 --
  target/loongarch/insn_trans/trans_bit.c.inc   | 12 ---
  target/loongarch/insn_trans/trans_fcmp.c.inc  |  3 --
  .../loongarch/insn_trans/trans_fmemory.c.inc  | 20 ++-
  target/loongarch/insn_trans/trans_fmov.c.inc  |  6 
  .../loongarch/insn_trans/trans_memory.c.inc   | 34 +++
  .../insn_trans/trans_privileged.c.inc |  4 ---
  target/loongarch/insn_trans/trans_shift.c.inc | 11 --
  9 files changed, 6 insertions(+), 99 deletions(-)

Reviewed-by: Song Gao 

Thanks.
Song Gao

diff --git a/target/loongarch/insn_trans/trans_arith.c.inc 
b/target/loongarch/insn_trans/trans_arith.c.inc
index 8e45eadbc8..43d6cf261d 100644
--- a/target/loongarch/insn_trans/trans_arith.c.inc
+++ b/target/loongarch/insn_trans/trans_arith.c.inc
@@ -100,14 +100,12 @@ static void gen_mulh_d(TCGv dest, TCGv src1, TCGv src2)
  {
  TCGv discard = tcg_temp_new();
  tcg_gen_muls2_tl(discard, dest, src1, src2);
-tcg_temp_free(discard);
  }
  
  static void gen_mulh_du(TCGv dest, TCGv src1, TCGv src2)

  {
  TCGv discard = tcg_temp_new();
  tcg_gen_mulu2_tl(discard, dest, src1, src2);
-tcg_temp_free(discard);
  }
  
  static void prep_divisor_d(TCGv ret, TCGv src1, TCGv src2)

@@ -129,9 +127,6 @@ static void prep_divisor_d(TCGv ret, TCGv src1, TCGv src2)
  tcg_gen_and_tl(ret, ret, t0);
  tcg_gen_or_tl(ret, ret, t1);
  tcg_gen_movcond_tl(TCG_COND_NE, ret, ret, zero, ret, src2);
-
-tcg_temp_free(t0);
-tcg_temp_free(t1);
  }
  
  static void prep_divisor_du(TCGv ret, TCGv src2)

@@ -152,7 +147,6 @@ static void gen_div_d(TCGv dest, TCGv src1, TCGv src2)
  TCGv t0 = tcg_temp_new();
  prep_divisor_d(t0, src1, src2);
  tcg_gen_div_tl(dest, src1, t0);
-tcg_temp_free(t0);
  }
  
  static void gen_rem_d(TCGv dest, TCGv src1, TCGv src2)

@@ -160,7 +154,6 @@ static void gen_rem_d(TCGv dest, TCGv src1, TCGv src2)
  TCGv t0 = tcg_temp_new();
  prep_divisor_d(t0, src1, src2);
  tcg_gen_rem_tl(dest, src1, t0);
-tcg_temp_free(t0);
  }
  
  static void gen_div_du(TCGv dest, TCGv src1, TCGv src2)

@@ -168,7 +161,6 @@ static void gen_div_du(TCGv dest, TCGv src1, TCGv src2)
  TCGv t0 = tcg_temp_new();
  prep_divisor_du(t0, src2);
  tcg_gen_divu_tl(dest, src1, t0);
-tcg_temp_free(t0);
  }
  
  static void gen_rem_du(TCGv dest, TCGv src1, TCGv src2)

@@ -176,7 +168,6 @@ static void gen_rem_du(TCGv dest, TCGv src1, TCGv src2)
  TCGv t0 = tcg_temp_new();
  prep_divisor_du(t0, src2);
  tcg_gen_remu_tl(dest, src1, t0);
-tcg_temp_free(t0);
  }
  
  static void gen_div_w(TCGv dest, TCGv src1, TCGv src2)

@@ -185,7 +176,6 @@ static void gen_div_w(TCGv dest, TCGv src1, TCGv src2)
  /* We need not check for integer overflow for div_w. */
  prep_divisor_du(t0, src2);
  tcg_gen_div_tl(dest, src1, t0);
-tcg_temp_free(t0);
  }
  
  static void gen_rem_w(TCGv dest, TCGv src1, TCGv src2)

@@ -194,7 +184,6 @@ static void gen_rem_w(TCGv dest, TCGv src1, TCGv src2)
  /* We need not check for integer overflow for rem_w. */
  prep_divisor_du(t0, src2);
  tcg_gen_rem_tl(dest, src1, t0);
-tcg_temp_free(t0);
  }
  
  static void gen_alsl(TCGv dest, TCGv src1, TCGv src2, target_long sa)

@@ -202,7 +191,6 @@ static void gen_alsl(TCGv dest, TCGv src1, TCGv src2, 
target_long sa)
  TCGv t0 = tcg_temp_new();
  tcg_gen_shli_tl(t0, src1, sa);
  tcg_gen_add_tl(dest, t0, src2);
-tcg_temp_free(t0);
  }
  
  static bool trans_lu32i_d(DisasContext *ctx, arg_lu32i_d *a)

diff --git a/target/loongarch/insn_trans/trans_atomic.c.inc 
b/target/loongarch/insn_trans/trans_atomic.c.inc
index 6763c1c301..612709f2a7 100644
--- a/target/loongarch/insn_trans/trans_atomic.c.inc
+++ b/target/loongarch/insn_trans/trans_atomic.c.inc
@@ -14,7 +14,6 @@ static bool gen_ll(DisasContext *ctx, arg_rr_i *a, MemOp mop)
  tcg_gen_st_tl(t0, cpu_env, offsetof(CPULoongArchState, lladdr));
  tcg_gen_st_tl(dest, cpu_env, offsetof(CPULoongArchState, llval));
  gen_set_gpr(a->rd, dest, EXT_NONE);
-tcg_temp_free(t0);
  
  return true;

  }
@@ -43,8 +42,6 @@ static bool gen_sc(DisasContext *ctx, arg_rr_i *a, MemOp mop)
  tcg_gen_setcond_tl(TCG_COND_EQ, dest, t0, cpu_llval);
  gen_set_label(done);
  gen_set_gpr(a->rd, dest, EXT_NONE);
-tcg_temp_free(t0);
-tcg_temp_free(val);
  
  return true;

  }
diff --git a/target/loongarch/insn_trans/trans_bit.c.inc 
b/target/loongarch/insn_trans/trans_bit.c.inc
index b01e4aeb23..25b4d7858b 100644
--- a/target/loongarch/insn_trans/trans_bit.c.inc
+++ b/target/loongarch/insn_trans/trans_bit.c.inc
@@ -122,9 +122,6 @@ static void gen_revb_2h(TCGv dest, TCGv src1)
  tcg_gen_and_tl(t1, src1, mask);

Adopting abandoned patch?

2023-02-26 Thread Dinah B
Hi,

I'm looking to get more involved in contributing to QEMU. I noticed that
there are some issues in the tracker where a sample patch has been
contributed but never got merged, like a proposal to add multiboot2
support: https://gitlab.com/qemu-project/qemu/-/issues/389

Is another dev allowed to "adopt" the patch as-is, with proper attribution
to the original dev and drive it to completion/merging (there are some
features missing)? Or is "starting from scratch" required for legal reasons?

Thanks,
-Dinah


[PATCH v2 1/2] docs/system/loongarch: update loongson3.rst and rename it to virt.rst

2023-02-26 Thread Song Gao
Since the EDK2 had already support LoongArch, update build bios,
and update cpu type, cross-tools.

Signed-off-by: Song Gao 
Message-Id: <20230208094133.2945979-1-gaos...@loongson.cn>
---
 .../loongarch/{loongson3.rst => virt.rst} | 97 ---
 1 file changed, 38 insertions(+), 59 deletions(-)
 rename docs/system/loongarch/{loongson3.rst => virt.rst} (51%)

diff --git a/docs/system/loongarch/loongson3.rst 
b/docs/system/loongarch/virt.rst
similarity index 51%
rename from docs/system/loongarch/loongson3.rst
rename to docs/system/loongarch/virt.rst
index 489ea20f8f..e3087246a3 100644
--- a/docs/system/loongarch/loongson3.rst
+++ b/docs/system/loongarch/virt.rst
@@ -19,14 +19,14 @@ The ``virt`` machine supports:
 - Fw_cfg device
 - PCI/PCIe devices
 - Memory device
-- CPU device. Type: la464-loongarch-cpu.
+- CPU device. Type: la464.
 
 CPU and machine Type
 
 
 The ``qemu-system-loongarch64`` provides emulation for virt
 machine. You can specify the machine type ``virt`` and
-cpu type ``la464-loongarch-cpu``.
+cpu type ``la464``.
 
 Boot options
 
@@ -35,95 +35,74 @@ We can boot the LoongArch virt machine by specifying the 
uefi bios,
 initrd, and linux kernel. And those source codes and binary files
 can be accessed by following steps.
 
-(1) booting command:
+(1) Build qemu-system-loongarch64:
 
 .. code-block:: bash
 
-  $ qemu-system-loongarch64 -machine virt -m 4G -cpu la464-loongarch-cpu \
-  -smp 1 -bios QEMU_EFI.fd -kernel vmlinuz.efi -initrd initrd.img \
-  -append "root=/dev/ram rdinit=/sbin/init console=ttyS0,115200" \
-  --nographic
-
-Note: The running speed may be a little slow, as the performance of our
-qemu and uefi bios is not perfect, and it is being fixed.
-
-(2) cross compiler tools:
-
-.. code-block:: bash
-
-  wget https://github.com/loongson/build-tools/releases/download/ \
-  2022.05.29/loongarch64-clfs-5.0-cross-tools-gcc-full.tar.xz
-
-  tar -vxf loongarch64-clfs-5.0-cross-tools-gcc-full.tar.xz
-
-(3) qemu compile configure option:
-
-.. code-block:: bash
-
-  ./configure --disable-rdma --disable-pvrdma --prefix=usr \
+  ./configure --disable-rdma --disable-pvrdma --prefix=/usr \
   --target-list="loongarch64-softmmu" \
   --disable-libiscsi --disable-libnfs --disable-libpmem \
   --disable-glusterfs --enable-libusb --enable-usb-redir \
   --disable-opengl --disable-xen --enable-spice \
   --enable-debug --disable-capstone --disable-kvm \
   --enable-profiler
-  make
+  make -j8
 
-(4) uefi bios source code and compile method:
+(2) Set cross tools:
 
 .. code-block:: bash
 
-  git clone https://github.com/loongson/edk2-LoongarchVirt.git
-
-  cd edk2-LoongarchVirt
-
-  git submodule update --init
-
-  export PATH=$YOUR_COMPILER_PATH/bin:$PATH
-
-  export WORKSPACE=`pwd`
+  wget 
https://github.com/loongson/build-tools/releases/download/2022.09.06/loongarch64-clfs-6.3-cross-tools-gcc-glibc.tar.xz
 
-  export PACKAGES_PATH=$WORKSPACE/edk2-LoongarchVirt
+  tar -vxf loongarch64-clfs-6.3-cross-tools-gcc-glibc.tar.xz  -C /opt
 
-  export GCC5_LOONGARCH64_PREFIX=loongarch64-unknown-linux-gnu-
+  export PATH=/opt/cross-tools/bin:$PATH
+  export LD_LIBRARY_PATH=/opt/cross-tools/lib:$LD_LIBRARY_PATH
+  export 
LD_LIBRARY_PATH=/opt/cross-tools/loongarch64-unknown-linux-gnu/lib/:$LD_LIBRARY_PATH
 
-  edk2-LoongarchVirt/edksetup.sh
+Note: You need get the latest cross-tools at 
https://github.com/loongson/build-tools
 
-  make -C edk2-LoongarchVirt/BaseTools
+(3) Build BIOS:
 
-  build --buildtarget=DEBUG --tagname=GCC5 --arch=LOONGARCH64  
--platform=OvmfPkg/LoongArchQemu/Loongson.dsc
+See: 
https://github.com/tianocore/edk2-platforms/tree/master/Platform/Loongson/LoongArchQemuPkg#readme
 
-  build --buildtarget=RELEASE --tagname=GCC5 --arch=LOONGARCH64  
--platform=OvmfPkg/LoongArchQemu/Loongson.dsc
+Note: build release bios need set --buildtarget=RELEASE,
+  the bios file path:  Build/LoongArchQemu/RELEASE_GCC5/FV/QEMU_EFI.fd
 
-The efi binary file path:
-
-  Build/LoongArchQemu/DEBUG_GCC5/FV/QEMU_EFI.fd
-
-  Build/LoongArchQemu/RELEASE_GCC5/FV/QEMU_EFI.fd
-
-(5) linux kernel source code and compile method:
+(4) Build kernel:
 
 .. code-block:: bash
 
   git clone https://github.com/loongson/linux.git
 
-  export PATH=$YOUR_COMPILER_PATH/bin:$PATH
-
-  export LD_LIBRARY_PATH=$YOUR_COMPILER_PATH/lib:$LD_LIBRARY_PATH
+  cd linux
 
-  export 
LD_LIBRARY_PATH=$YOUR_COMPILER_PATH/loongarch64-unknown-linux-gnu/lib/:$LD_LIBRARY_PATH
+  git checkout loongarch-next
 
   make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu- 
loongson3_defconfig
 
-  make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu-
-
-  make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu- install
-
-  make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu- 
modules_install
+  make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu- -j32
 
 Note

[PATCH v2 2/2] loongarch: Add smbios command line option.

2023-02-26 Thread Song Gao
LoongArch has enabled CONFIG_SMBIOS, but didn't enable CLI '-smbios'.

Fixes: 3efa6fa1e629 ("hw/loongarch: Add smbios support")
Acked-by: Michael S. Tsirkin 
Reviewed-by: Markus Armbruster 
Signed-off-by: Song Gao 
Message-Id: <20230208094133.2945979-2-gaos...@loongson.cn>
---
 qemu-options.hx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index beeb4475ba..d42f60fb91 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2585,7 +2585,7 @@ DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
 "specify SMBIOS type 17 fields\n"
 "-smbios type=41[,designation=str][,kind=str][,instance=%d][,pcidev=str]\n"
 "specify SMBIOS type 41 fields\n",
-QEMU_ARCH_I386 | QEMU_ARCH_ARM)
+QEMU_ARCH_I386 | QEMU_ARCH_ARM | QEMU_ARCH_LOONGARCH)
 SRST
 ``-smbios file=binary``
 Load SMBIOS entry from binary file.
-- 
2.31.1




Re: [PATCH 3/5] qmp: Added the helper stamp check.

2023-02-26 Thread Andrew Melnichenko
Hi all,

On Mon, Feb 20, 2023 at 11:50 AM Daniel P. Berrangé  wrote:
>
> On Sun, Feb 19, 2023 at 06:20:58PM +0200, Andrew Melnychenko wrote:
> > Added a function to check the stamp in the helper.
> > eBPF helper should have a special symbol that generates during the build.
> > QEMU checks the helper and determines that it fits, so the helper
> > will produce proper output.
>
> I think this is quite limiting for in place upgrades.
>
> Consider this scenario
>
>  * Host has QEMU 8.1.0 installed
>  * VM is running QEMU 8.1.0
>  * QEMU 8.1.1 is released with a bug fix in the EBF program
>  * Host is upgraded to QEMU 8.1.1
>  * User attempts to hotplug a NIC to the running VM
>
> IIUC this last step is going to fail because we'll be loading
> the EBF program from 8.1.1 and so its hash is different from
> that expected by the QEMU 8.1.0 that the pre-existing VM is
> running.
>
> If some changes to the EBF program are not going to be back
> compatible from the POV of the QEMU process, should we instead
> be versioning the EBF program. eg so new QEMU will ship both
> the old and new versions of the EBF program.
>

I think it's too complicated to maintain backward compatibility with
eBPF programs in "one package".
As we can see, the eBPF skeleton may be changed not only by bugfix but
with changes in libbpf(g.e. libbpf 1.0.1+).
This may lead to issues when with a newer environment you can't
consistently recreate the "old" skeleton.

To solve the case - we need to "save" the halper from an old package somehow.

>
> With regards,
> Daniel
> --
> |: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o-https://fstop138.berrange.com :|
> |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|
>



Re: [PATCH 4/5] ebpf_rss_helper: Added helper for eBPF RSS.

2023-02-26 Thread Andrew Melnichenko
Hi,

On Mon, Feb 20, 2023 at 11:54 AM Daniel P. Berrangé  wrote:
>
> On Sun, Feb 19, 2023 at 06:20:59PM +0200, Andrew Melnychenko wrote:
> > Helper program. Loads eBPF RSS program and maps and passes them through 
> > unix socket.
> > Libvirt may launch this helper and pass eBPF fds to qemu virtio-net.
> > Also, libbpf dependency for now is exclusively for Linux.
> > Libbpf is used for eBPF RSS steering, which is supported only by Linux TAP.
> > There is no reason yet to build eBPF loader and helper for non-Linux 
> > systems,
> > even if libbpf is present.
> >
> > Signed-off-by: Andrew Melnychenko 
> > ---
> >  ebpf/qemu-ebpf-rss-helper.c | 132 
> >  meson.build |  37 ++
> >  2 files changed, 156 insertions(+), 13 deletions(-)
> >  create mode 100644 ebpf/qemu-ebpf-rss-helper.c
> >
> > diff --git a/ebpf/qemu-ebpf-rss-helper.c b/ebpf/qemu-ebpf-rss-helper.c
> > new file mode 100644
> > index 00..348d26bcdd
> > --- /dev/null
> > +++ b/ebpf/qemu-ebpf-rss-helper.c
> > @@ -0,0 +1,132 @@
> > +/*
> > + * eBPF RSS Helper
> > + *
> > + * Developed by Daynix Computing LTD (http://www.daynix.com)
> > + *
> > + * Authors:
> > + *  Andrew Melnychenko 
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2.  See
> > + * the COPYING file in the top-level directory.
>
> Is there a reason for specifying GPL version 2 only ?
>
> Unless this has copied code from one of the existing GPLv2-only files
> in QEMU, the requirement (listed in LICENSE) is that new contributions
> will be GPLv2-or-later, except for a handful of sub-directories.
>

Yeah - I'll change it. Thank you.

>
>
> > + *
> > + * Description: This is helper program for libvirtd.
> > + *  It loads eBPF RSS program and passes fds through unix 
> > socket.
> > + *  Built by meson, target - 'qemu-ebpf-rss-helper'.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "ebpf_rss.h"
> > +
> > +#include "qemu-ebpf-rss-helper-stamp.h"
> > +
> > +void QEMU_EBPF_RSS_HELPER_STAMP(void) {}
> > +
> > +static int send_fds(int socket, int *fds, int n)
> > +{
> > +struct msghdr msg = {};
> > +struct cmsghdr *cmsg = NULL;
> > +char buf[CMSG_SPACE(n * sizeof(int))];
> > +char dummy_buffer = 0;
> > +struct iovec io = { .iov_base = &dummy_buffer,
> > +.iov_len = sizeof(dummy_buffer) };
> > +
> > +memset(buf, 0, sizeof(buf));
> > +
> > +msg.msg_iov = &io;
> > +msg.msg_iovlen = 1;
> > +msg.msg_control = buf;
> > +msg.msg_controllen = sizeof(buf);
> > +
> > +cmsg = CMSG_FIRSTHDR(&msg);
> > +cmsg->cmsg_level = SOL_SOCKET;
> > +cmsg->cmsg_type = SCM_RIGHTS;
> > +cmsg->cmsg_len = CMSG_LEN(n * sizeof(int));
> > +
> > +memcpy(CMSG_DATA(cmsg), fds, n * sizeof(int));
> > +
> > +return sendmsg(socket, &msg, 0);
> > +}
> > +
> > +static void print_help_and_exit(const char *prog, int exitcode)
> > +{
> > +fprintf(stderr, "%s - load eBPF RSS program for qemu and pass eBPF fds"
> > +" through unix socket.\n", prog);
> > +fprintf(stderr, "\t--fd , -f  - unix socket file descriptor"
> > +" used to pass eBPF fds.\n");
> > +fprintf(stderr, "\t--help, -h - this help.\n");
> > +exit(exitcode);
> > +}
> > +
> > +int main(int argc, char **argv)
> > +{
> > +char *fd_string = NULL;
> > +int unix_fd = 0;
> > +struct EBPFRSSContext ctx = {};
> > +int fds[EBPF_RSS_MAX_FDS] = {};
> > +int ret = -1;
> > +
> > +for (;;) {
> > +int c;
> > +static struct option long_options[] = {
> > +{"help",  no_argument, 0, 'h'},
> > +{"fd",  required_argument, 0, 'f'},
> > +{0, 0, 0, 0}
> > +};
> > +c = getopt_long(argc, argv, "hf:",
> > +long_options, NULL);
> > +
> > +if (c == -1) {
> > +break;
> > +}
> > +
> > +switch (c) {
> > +case 'f':
> > +fd_string = optarg;
> > +break;
> > +case 'h':
> > +default:
> > +print_help_and_exit(argv[0],
> > +c == 'h' ? EXIT_SUCCESS : EXIT_FAILURE);
> > +}
> > +}
> > +
> > +if (!fd_string) {
> > +fprintf(stderr, "Unix file descriptor not present.\n");
> > +print_help_and_exit(argv[0], EXIT_FAILURE);
> > +}
> > +
> > +unix_fd = atoi(fd_string);
> > +
> > +if (!unix_fd) {
> > +fprintf(stderr, "Unix file descriptor is invalid.\n");
> > +return EXIT_FAILURE;
> > +}
> > +
> > +ebpf_rss_init(&ctx);
> > +if (!ebpf_rss_load(&ctx)) {
> > +fprintf(stderr, "Can't load ebpf.\n");
> > +return EXIT_FAILURE;
> > +}
> > +fds[0] = ctx.program_fd;
> > +fds[1] = ctx.map_configuration;
> > +fds[2] = ctx.map_toeplitz_key;
> > +fds[3] = 

[PATCH v2 2/4] kvm: Synchronize the backup bitmap in the last stage

2023-02-26 Thread Gavin Shan
In the last stage of live migration or memory slot removal, the
backup bitmap needs to be synchronized when it has been enabled.

Signed-off-by: Gavin Shan 
Reviewed-by: Peter Xu 
Tested-by: Zhenyu Zhang 
---
 accel/kvm/kvm-all.c  | 11 +++
 include/sysemu/kvm_int.h |  1 +
 2 files changed, 12 insertions(+)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 01a6a026af..b5e12de522 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1352,6 +1352,10 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
  */
 if (kvm_state->kvm_dirty_ring_size) {
 kvm_dirty_ring_reap_locked(kvm_state, NULL);
+if (kvm_state->kvm_dirty_ring_with_bitmap) {
+kvm_slot_sync_dirty_pages(mem);
+kvm_slot_get_dirty_log(kvm_state, mem);
+}
 } else {
 kvm_slot_get_dirty_log(kvm_state, mem);
 }
@@ -1573,6 +1577,12 @@ static void kvm_log_sync_global(MemoryListener *l, bool 
last_stage)
 mem = &kml->slots[i];
 if (mem->memory_size && mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
 kvm_slot_sync_dirty_pages(mem);
+
+if (s->kvm_dirty_ring_with_bitmap && last_stage &&
+kvm_slot_get_dirty_log(s, mem)) {
+kvm_slot_sync_dirty_pages(mem);
+}
+
 /*
  * This is not needed by KVM_GET_DIRTY_LOG because the
  * ioctl will unconditionally overwrite the whole region.
@@ -3701,6 +3711,7 @@ static void kvm_accel_instance_init(Object *obj)
 s->kernel_irqchip_split = ON_OFF_AUTO_AUTO;
 /* KVM dirty ring is by default off */
 s->kvm_dirty_ring_size = 0;
+s->kvm_dirty_ring_with_bitmap = false;
 s->notify_vmexit = NOTIFY_VMEXIT_OPTION_RUN;
 s->notify_window = 0;
 }
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index 60b520a13e..fdd5b1bde0 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -115,6 +115,7 @@ struct KVMState
 } *as;
 uint64_t kvm_dirty_ring_bytes;  /* Size of the per-vcpu dirty ring */
 uint32_t kvm_dirty_ring_size;   /* Number of dirty GFNs per ring */
+bool kvm_dirty_ring_with_bitmap;
 struct KVMDirtyRingReaper reaper;
 NotifyVmexitOption notify_vmexit;
 uint32_t notify_window;
-- 
2.23.0




[PATCH v2 4/4] kvm: Enable dirty ring for arm64

2023-02-26 Thread Gavin Shan
arm64 has different capability from x86 to enable the dirty ring, which
is KVM_CAP_DIRTY_LOG_RING_ACQ_REL. Besides, arm64 also needs the backup
bitmap extension (KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP) when 'kvm-arm-gicv3'
or 'arm-its-kvm' device is enabled. Here the extension is always enabled
and the unnecessary overhead to do the last stage of dirty log synchronization
when those two devices aren't used is introduced, but the overhead should
be very small and acceptable. The benefit is cover future cases where those
two devices are used without modifying the code.

Signed-off-by: Gavin Shan 
Reviewed-by: Juan Quintela 
Tested-by: Zhenyu Zhang 
---
 accel/kvm/kvm-all.c | 23 +--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index e5035026c9..d96bca618b 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1457,6 +1457,7 @@ static int kvm_dirty_ring_init(KVMState *s)
 {
 uint32_t ring_size = s->kvm_dirty_ring_size;
 uint64_t ring_bytes = ring_size * sizeof(struct kvm_dirty_gfn);
+unsigned int capability = KVM_CAP_DIRTY_LOG_RING;
 int ret;
 
 s->kvm_dirty_ring_size = 0;
@@ -1471,7 +1472,12 @@ static int kvm_dirty_ring_init(KVMState *s)
  * Read the max supported pages. Fall back to dirty logging mode
  * if the dirty ring isn't supported.
  */
-ret = kvm_vm_check_extension(s, KVM_CAP_DIRTY_LOG_RING);
+ret = kvm_vm_check_extension(s, capability);
+if (ret <= 0) {
+capability = KVM_CAP_DIRTY_LOG_RING_ACQ_REL;
+ret = kvm_vm_check_extension(s, capability);
+}
+
 if (ret <= 0) {
 warn_report("KVM dirty ring not available, using bitmap method");
 return 0;
@@ -1484,13 +1490,26 @@ static int kvm_dirty_ring_init(KVMState *s)
 return -EINVAL;
 }
 
-ret = kvm_vm_enable_cap(s, KVM_CAP_DIRTY_LOG_RING, 0, ring_bytes);
+ret = kvm_vm_enable_cap(s, capability, 0, ring_bytes);
 if (ret) {
 error_report("Enabling of KVM dirty ring failed: %s. "
  "Suggested minimum value is 1024.", strerror(-ret));
 return -EIO;
 }
 
+/* Enable the backup bitmap if it is supported */
+ret = kvm_vm_check_extension(s, KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP);
+if (ret > 0) {
+ret = kvm_vm_enable_cap(s, KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP, 0);
+if (ret) {
+error_report("Enabling of KVM dirty ring's backup bitmap failed: "
+ "%s. ", strerror(-ret));
+return -EIO;
+}
+
+s->kvm_dirty_ring_with_bitmap = true;
+}
+
 s->kvm_dirty_ring_size = ring_size;
 s->kvm_dirty_ring_bytes = ring_bytes;
 
-- 
2.23.0




[PATCH v2 0/4] hw/arm/virt: Support dirty ring

2023-02-26 Thread Gavin Shan
This series intends to support dirty ring for live migration for arm64. The
dirty ring use discrete buffer to track dirty pages. For arm64, the speciality
is to use backup bitmap to track dirty pages when there is no-running-vcpu
context. It's known that the backup bitmap needs to be synchronized when
KVM device "kvm-arm-gicv3" or "arm-its-kvm" has been enabled. The backup
bitmap is collected in the last stage of migration. The policy here is to
always enable the backup bitmap extension. The overhead to synchronize the
backup bitmap in the last stage of migration, when those two devices aren't
used, is introduced. However, the overhead should be very small and acceptable.
The benefit is to support future cases where those two devices are used without
modifying the code.

PATCH[1] add migration last stage indicator
PATCH[2] synchronize the backup bitmap in the last stage of migration
PATCH[3] add helper kvm_dirty_ring_init() to enable dirty ring
PATCH[4] enable dirty ring for arm64

   v1: https://lists.nongnu.org/archive/html/qemu-arm/2023-02/msg00434.html
RFCv1: https://lists.nongnu.org/archive/html/qemu-arm/2023-02/msg00171.html

Testing
===
(1) kvm-unit-tests/its-pending-migration and kvm-unit-tests/its-migration with
dirty ring or normal dirty page tracking mechanism. All test cases passed.

QEMU=./qemu.main/build/qemu-system-aarch64 ACCEL=kvm \
./its-pending-migration

QEMU=./qemu.main/build/qemu-system-aarch64 ACCEL=kvm \
./its-migration

QEMU=./qemu.main/build/qemu-system-aarch64 ACCEL=kvm,dirty-ring-size=65536 \
./its-pending-migration

QEMU=./qemu.main/build/qemu-system-aarch64 ACCEL=kvm,dirty-ring-size=65536 \
./its-migration

(2) Combinations of migration, post-copy migration, e1000e and virtio-net
devices. All test cases passed.

-netdev tap,id=net0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown  \
-device e1000e,bus=pcie.5,netdev=net0,mac=52:54:00:f1:26:a0

-netdev tap,id=vnet0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown \
-device virtio-net-pci,bus=pcie.6,netdev=vnet0,mac=52:54:00:f1:26:b0

Changelog
=
v2:
  * Drop PATCH[v1 1/6] to synchronize linux-headers
(Gavin)
  * More restrictive comments about struct MemoryListener::log_sync_global 
(PeterX)
  * Always enable the backup bitmap extension  
(PeterM)
v1:
  * Combine two patches into one PATCH[v1 2/6] for the last stage indicator
(PeterX)
  * Drop the secondary bitmap and use the original one directly
(Juan)
  * Avoid "goto out" in helper kvm_dirty_ring_init()   
(Juan)


Gavin Shan (4):
  migration: Add last stage indicator to global dirty log
synchronization
  kvm: Synchronize the backup bitmap in the last stage
  kvm: Add helper kvm_dirty_ring_init()
  kvm: Enable dirty ring for arm64

 accel/kvm/kvm-all.c  | 108 ---
 include/exec/memory.h|   7 ++-
 include/sysemu/kvm_int.h |   1 +
 migration/dirtyrate.c|   4 +-
 migration/ram.c  |  20 
 softmmu/memory.c |  10 ++--
 6 files changed, 101 insertions(+), 49 deletions(-)

-- 
2.23.0




[PATCH v2 1/4] migration: Add last stage indicator to global dirty log synchronization

2023-02-26 Thread Gavin Shan
The global dirty log synchronization is used when KVM and dirty ring
are enabled. There is a particularity for ARM64 where the backup
bitmap is used to track dirty pages in non-running-vcpu situations.
It means the dirty ring works with the combination of ring buffer
and backup bitmap. The dirty bits in the backup bitmap needs to
collected in the last stage of live migration.

In order to identify the last stage of live migration and pass it
down, an extra parameter is added to the relevant functions and
callbacks. This last stage indicator isn't used until the dirty
ring is enabled in the subsequent patches.

No functional change intended.

Signed-off-by: Gavin Shan 
Reviewed-by: Peter Xu 
Tested-by: Zhenyu Zhang 
---
 accel/kvm/kvm-all.c   |  2 +-
 include/exec/memory.h |  7 +--
 migration/dirtyrate.c |  4 ++--
 migration/ram.c   | 20 ++--
 softmmu/memory.c  | 10 +-
 5 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 9b26582655..01a6a026af 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1554,7 +1554,7 @@ static void kvm_log_sync(MemoryListener *listener,
 kvm_slots_unlock();
 }
 
-static void kvm_log_sync_global(MemoryListener *l)
+static void kvm_log_sync_global(MemoryListener *l, bool last_stage)
 {
 KVMMemoryListener *kml = container_of(l, KVMMemoryListener, listener);
 KVMState *s = kvm_state;
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 2e602a2fad..b5463b3a7a 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -929,8 +929,11 @@ struct MemoryListener {
  * its @log_sync must be NULL.  Vice versa.
  *
  * @listener: The #MemoryListener.
+ * @last_stage: The last stage to synchronize the log during migration.
+ * The caller should gurantee that the synchronization with true for
+ * @last_stage is triggered for once after all VCPUs have been stopped.
  */
-void (*log_sync_global)(MemoryListener *listener);
+void (*log_sync_global)(MemoryListener *listener, bool last_stage);
 
 /**
  * @log_clear:
@@ -2408,7 +2411,7 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr,
  *
  * Synchronizes the dirty page log for all address spaces.
  */
-void memory_global_dirty_log_sync(void);
+void memory_global_dirty_log_sync(bool last_stage);
 
 /**
  * memory_global_dirty_log_sync: synchronize the dirty log for all memory
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 575d48c397..da9b4a1f8d 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -101,7 +101,7 @@ void global_dirty_log_change(unsigned int flag, bool start)
 static void global_dirty_log_sync(unsigned int flag, bool one_shot)
 {
 qemu_mutex_lock_iothread();
-memory_global_dirty_log_sync();
+memory_global_dirty_log_sync(false);
 if (one_shot) {
 memory_global_dirty_log_stop(flag);
 }
@@ -553,7 +553,7 @@ static void calculate_dirtyrate_dirty_bitmap(struct 
DirtyRateConfig config)
  * skip it unconditionally and start dirty tracking
  * from 2'round of log sync
  */
-memory_global_dirty_log_sync();
+memory_global_dirty_log_sync(false);
 
 /*
  * reset page protect manually and unconditionally.
diff --git a/migration/ram.c b/migration/ram.c
index 96e8a19a58..22e712c8b9 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1217,7 +1217,7 @@ static void migration_trigger_throttle(RAMState *rs)
 }
 }
 
-static void migration_bitmap_sync(RAMState *rs)
+static void migration_bitmap_sync(RAMState *rs, bool last_stage)
 {
 RAMBlock *block;
 int64_t end_time;
@@ -1229,7 +1229,7 @@ static void migration_bitmap_sync(RAMState *rs)
 }
 
 trace_migration_bitmap_sync_start();
-memory_global_dirty_log_sync();
+memory_global_dirty_log_sync(last_stage);
 
 qemu_mutex_lock(&rs->bitmap_mutex);
 WITH_RCU_READ_LOCK_GUARD() {
@@ -1263,7 +1263,7 @@ static void migration_bitmap_sync(RAMState *rs)
 }
 }
 
-static void migration_bitmap_sync_precopy(RAMState *rs)
+static void migration_bitmap_sync_precopy(RAMState *rs, bool last_stage)
 {
 Error *local_err = NULL;
 
@@ -1276,7 +1276,7 @@ static void migration_bitmap_sync_precopy(RAMState *rs)
 local_err = NULL;
 }
 
-migration_bitmap_sync(rs);
+migration_bitmap_sync(rs, last_stage);
 
 if (precopy_notify(PRECOPY_NOTIFY_AFTER_BITMAP_SYNC, &local_err)) {
 error_report_err(local_err);
@@ -2937,7 +2937,7 @@ void ram_postcopy_send_discard_bitmap(MigrationState *ms)
 RCU_READ_LOCK_GUARD();
 
 /* This should be our last sync, the src is now paused */
-migration_bitmap_sync(rs);
+migration_bitmap_sync(rs, false);
 
 /* Easiest way to make sure we don't resume in the middle of a host-page */
 rs->pss[RAM_CHANNEL_PRECOPY].last_sent_block = NULL;
@@ -3128,7 +3128,7 @@ static void ram_init_bitmaps(RAMState *rs)
 /* We don't use dirty log with backgrou

[PATCH v2 3/4] kvm: Add helper kvm_dirty_ring_init()

2023-02-26 Thread Gavin Shan
Due to multiple capabilities associated with the dirty ring for different
architectures: KVM_CAP_DIRTY_{LOG_RING, LOG_RING_ACQ_REL} for x86 and
arm64 separately. There will be more to be done in order to support the
dirty ring for arm64.

Lets add helper kvm_dirty_ring_init() to enable the dirty ring. With this,
the code looks a bit clean.

No functional change intended.

Signed-off-by: Gavin Shan 
Reviewed-by: Peter Xu 
Tested-by: Zhenyu Zhang 
---
 accel/kvm/kvm-all.c | 76 -
 1 file changed, 47 insertions(+), 29 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index b5e12de522..e5035026c9 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1453,6 +1453,50 @@ static int kvm_dirty_ring_reaper_init(KVMState *s)
 return 0;
 }
 
+static int kvm_dirty_ring_init(KVMState *s)
+{
+uint32_t ring_size = s->kvm_dirty_ring_size;
+uint64_t ring_bytes = ring_size * sizeof(struct kvm_dirty_gfn);
+int ret;
+
+s->kvm_dirty_ring_size = 0;
+s->kvm_dirty_ring_bytes = 0;
+
+/* Bail if the dirty ring size isn't specified */
+if (!ring_size) {
+return 0;
+}
+
+/*
+ * Read the max supported pages. Fall back to dirty logging mode
+ * if the dirty ring isn't supported.
+ */
+ret = kvm_vm_check_extension(s, KVM_CAP_DIRTY_LOG_RING);
+if (ret <= 0) {
+warn_report("KVM dirty ring not available, using bitmap method");
+return 0;
+}
+
+if (ring_bytes > ret) {
+error_report("KVM dirty ring size %" PRIu32 " too big "
+ "(maximum is %ld).  Please use a smaller value.",
+ ring_size, (long)ret / sizeof(struct kvm_dirty_gfn));
+return -EINVAL;
+}
+
+ret = kvm_vm_enable_cap(s, KVM_CAP_DIRTY_LOG_RING, 0, ring_bytes);
+if (ret) {
+error_report("Enabling of KVM dirty ring failed: %s. "
+ "Suggested minimum value is 1024.", strerror(-ret));
+return -EIO;
+}
+
+s->kvm_dirty_ring_size = ring_size;
+s->kvm_dirty_ring_bytes = ring_bytes;
+
+return 0;
+}
+
 static void kvm_region_add(MemoryListener *listener,
MemoryRegionSection *section)
 {
@@ -2522,35 +2566,9 @@ static int kvm_init(MachineState *ms)
  * Enable KVM dirty ring if supported, otherwise fall back to
  * dirty logging mode
  */
-if (s->kvm_dirty_ring_size > 0) {
-uint64_t ring_bytes;
-
-ring_bytes = s->kvm_dirty_ring_size * sizeof(struct kvm_dirty_gfn);
-
-/* Read the max supported pages */
-ret = kvm_vm_check_extension(s, KVM_CAP_DIRTY_LOG_RING);
-if (ret > 0) {
-if (ring_bytes > ret) {
-error_report("KVM dirty ring size %" PRIu32 " too big "
- "(maximum is %ld).  Please use a smaller value.",
- s->kvm_dirty_ring_size,
- (long)ret / sizeof(struct kvm_dirty_gfn));
-ret = -EINVAL;
-goto err;
-}
-
-ret = kvm_vm_enable_cap(s, KVM_CAP_DIRTY_LOG_RING, 0, ring_bytes);
-if (ret) {
-error_report("Enabling of KVM dirty ring failed: %s. "
- "Suggested minimum value is 1024.", 
strerror(-ret));
-goto err;
-}
-
-s->kvm_dirty_ring_bytes = ring_bytes;
- } else {
- warn_report("KVM dirty ring not available, using bitmap method");
- s->kvm_dirty_ring_size = 0;
-}
+ret = kvm_dirty_ring_init(s);
+if (ret < 0) {
+goto err;
 }
 
 /*
-- 
2.23.0




[PATCH] firmware: qemu_fw_cfg: make kobj_type structure constant

2023-02-26 Thread Thomas Weißschuh
Since commit ee6d3dd4ed48 ("driver core: make kobj_type constant.")
the driver core allows the usage of const struct kobj_type.

Take advantage of this to constify the structure definition to prevent
modification at runtime.

Signed-off-by: Thomas Weißschuh 
---
 drivers/firmware/qemu_fw_cfg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
index a69399a6b7c0..f41de793f41b 100644
--- a/drivers/firmware/qemu_fw_cfg.c
+++ b/drivers/firmware/qemu_fw_cfg.c
@@ -452,7 +452,7 @@ static void fw_cfg_sysfs_release_entry(struct kobject *kobj)
 }
 
 /* kobj_type: ties together all properties required to register an entry */
-static struct kobj_type fw_cfg_sysfs_entry_ktype = {
+static const struct kobj_type fw_cfg_sysfs_entry_ktype = {
.default_groups = fw_cfg_sysfs_entry_groups,
.sysfs_ops = &fw_cfg_sysfs_attr_ops,
.release = fw_cfg_sysfs_release_entry,

---
base-commit: 2fcd07b7ccd5fd10b2120d298363e4e6c53ccf9c
change-id: 20230227-kobj_type-firmware-qemu-7746b6320db0

Best regards,
-- 
Thomas Weißschuh 




[PATCH v2 01/76] tcg: Remove tcg_check_temp_count, tcg_clear_temp_count

2023-02-26 Thread Richard Henderson
Since all temps allocated by guest front-ends are now TEMP_TB,
and we don't recycle TEMP_TB, there's no point in requiring
that the front-ends free the temps at all.  Begin by dropping
the inner-most checks that all temps have been freed.

Signed-off-by: Richard Henderson 
---
 include/tcg/tcg.h  | 14 ---
 accel/tcg/translator.c | 12 --
 tcg/tcg.c  | 54 +++---
 3 files changed, 8 insertions(+), 72 deletions(-)

diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 7e2b954dbc..e8f73115ec 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -567,7 +567,6 @@ struct TCGContext {
 #endif
 
 #ifdef CONFIG_DEBUG_TCG
-int temps_in_use;
 int goto_tb_issue_mask;
 const TCGOpcode *vecop_list;
 #endif
@@ -958,19 +957,6 @@ static inline TCGv_ptr tcg_temp_new_ptr(void)
 return temp_tcgv_ptr(t);
 }
 
-#if defined(CONFIG_DEBUG_TCG)
-/* If you call tcg_clear_temp_count() at the start of a section of
- * code which is not supposed to leak any TCG temporaries, then
- * calling tcg_check_temp_count() at the end of the section will
- * return 1 if the section did in fact leak a temporary.
- */
-void tcg_clear_temp_count(void);
-int tcg_check_temp_count(void);
-#else
-#define tcg_clear_temp_count() do { } while (0)
-#define tcg_check_temp_count() 0
-#endif
-
 int64_t tcg_cpu_exec_time(void);
 void tcg_dump_info(GString *buf);
 void tcg_dump_op_count(GString *buf);
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
index 62e8f28025..88567a88d1 100644
--- a/accel/tcg/translator.c
+++ b/accel/tcg/translator.c
@@ -18,17 +18,8 @@
 #include "exec/plugin-gen.h"
 #include "sysemu/replay.h"
 
-/* Pairs with tcg_clear_temp_count.
-   To be called by #TranslatorOps.{translate_insn,tb_stop} if
-   (1) the target is sufficiently clean to support reporting,
-   (2) as and when all temporaries are known to be consumed.
-   For most targets, (2) is at the end of translate_insn.  */
 void translator_loop_temp_check(DisasContextBase *db)
 {
-if (tcg_check_temp_count()) {
-qemu_log("warning: TCG temporary leaks before "
- TARGET_FMT_lx "\n", db->pc_next);
-}
 }
 
 bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest)
@@ -67,9 +58,6 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int 
*max_insns,
 ops->init_disas_context(db, cpu);
 tcg_debug_assert(db->is_jmp == DISAS_NEXT);  /* no early exit */
 
-/* Reset the temp count so that we can identify leaks */
-tcg_clear_temp_count();
-
 /* Start translating.  */
 gen_tb_start(db->tb);
 ops->tb_start(db, cpu);
diff --git a/tcg/tcg.c b/tcg/tcg.c
index b65f2ffdbe..e3c0fa1012 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1272,7 +1272,7 @@ TCGTemp *tcg_temp_new_internal(TCGType type, TCGTempKind 
kind)
 ts->temp_allocated = 1;
 tcg_debug_assert(ts->base_type == type);
 tcg_debug_assert(ts->kind == kind);
-goto done;
+return ts;
 }
 } else {
 tcg_debug_assert(kind == TEMP_TB);
@@ -1316,11 +1316,6 @@ TCGTemp *tcg_temp_new_internal(TCGType type, TCGTempKind 
kind)
 ts2->kind = kind;
 }
 }
-
- done:
-#if defined(CONFIG_DEBUG_TCG)
-s->temps_in_use++;
-#endif
 return ts;
 }
 
@@ -1365,30 +1360,18 @@ void tcg_temp_free_internal(TCGTemp *ts)
 
 switch (ts->kind) {
 case TEMP_CONST:
-/*
- * In order to simplify users of tcg_constant_*,
- * silently ignore free.
- */
-return;
-case TEMP_EBB:
 case TEMP_TB:
+/* Silently ignore free. */
+break;
+case TEMP_EBB:
+tcg_debug_assert(ts->temp_allocated != 0);
+ts->temp_allocated = 0;
+set_bit(temp_idx(ts), s->free_temps[ts->base_type].l);
 break;
 default:
+/* It never made sense to free TEMP_FIXED or TEMP_GLOBAL. */
 g_assert_not_reached();
 }
-
-tcg_debug_assert(ts->temp_allocated != 0);
-ts->temp_allocated = 0;
-
-#if defined(CONFIG_DEBUG_TCG)
-assert(s->temps_in_use > 0);
-s->temps_in_use--;
-#endif
-
-if (ts->kind == TEMP_EBB) {
-int idx = temp_idx(ts);
-set_bit(idx, s->free_temps[ts->base_type].l);
-}
 }
 
 TCGTemp *tcg_constant_internal(TCGType type, int64_t val)
@@ -1476,27 +1459,6 @@ TCGv_i64 tcg_const_i64(int64_t val)
 return t0;
 }
 
-#if defined(CONFIG_DEBUG_TCG)
-void tcg_clear_temp_count(void)
-{
-TCGContext *s = tcg_ctx;
-s->temps_in_use = 0;
-}
-
-int tcg_check_temp_count(void)
-{
-TCGContext *s = tcg_ctx;
-if (s->temps_in_use) {
-/* Clear the count so that we don't give another
- * warning immediately next time around.
- */
-s->temps_in_use = 0;
-return 1;
-}
-return 0;
-}
-#endif
-
 /* Return true if OP may appear in the opcode stream.
Test the runtime variable that controls each opcode.  */
 bool tcg_op_supported(TCGOpcode 

[PATCH v2 13/76] target/arm: Drop tcg_temp_free from translator-neon.c

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-neon.c | 131 +---
 1 file changed, 1 insertion(+), 130 deletions(-)

diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
index 4016339d46..af8685a4ac 100644
--- a/target/arm/translate-neon.c
+++ b/target/arm/translate-neon.c
@@ -182,7 +182,6 @@ static bool do_neon_ddda_fpst(DisasContext *s, int q, int 
vd, int vn, int vm,
vfp_reg_offset(1, vm),
vfp_reg_offset(1, vd),
fpst, opr_sz, opr_sz, data, fn_gvec_ptr);
-tcg_temp_free_ptr(fpst);
 return true;
 }
 
@@ -236,7 +235,6 @@ static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
vfp_reg_offset(1, a->vm),
fpst, opr_sz, opr_sz, a->rot,
fn_gvec_ptr);
-tcg_temp_free_ptr(fpst);
 return true;
 }
 
@@ -433,7 +431,6 @@ static void gen_neon_ldst_base_update(DisasContext *s, int 
rm, int rn,
 TCGv_i32 index;
 index = load_reg(s, rm);
 tcg_gen_add_i32(base, base, index);
-tcg_temp_free_i32(index);
 }
 store_reg(s, rn, base);
 }
@@ -536,8 +533,6 @@ static bool trans_VLDST_multiple(DisasContext *s, 
arg_VLDST_multiple *a)
 }
 }
 }
-tcg_temp_free_i32(addr);
-tcg_temp_free_i64(tmp64);
 
 gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
 return true;
@@ -630,8 +625,6 @@ static bool trans_VLD_all_lanes(DisasContext *s, 
arg_VLD_all_lanes *a)
 /* Subsequent memory operations inherit alignment */
 mop &= ~MO_AMASK;
 }
-tcg_temp_free_i32(tmp);
-tcg_temp_free_i32(addr);
 
 gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << size) * nregs);
 
@@ -751,8 +744,6 @@ static bool trans_VLDST_single(DisasContext *s, 
arg_VLDST_single *a)
 /* Subsequent memory operations inherit alignment */
 mop &= ~MO_AMASK;
 }
-tcg_temp_free_i32(addr);
-tcg_temp_free_i32(tmp);
 
 gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << a->size) * nregs);
 
@@ -1061,9 +1052,6 @@ static bool do_3same_pair(DisasContext *s, arg_3same *a, 
NeonGenTwoOpFn *fn)
 write_neon_element32(tmp, a->vd, 0, MO_32);
 write_neon_element32(tmp3, a->vd, 1, MO_32);
 
-tcg_temp_free_i32(tmp);
-tcg_temp_free_i32(tmp2);
-tcg_temp_free_i32(tmp3);
 return true;
 }
 
@@ -1126,7 +1114,6 @@ DO_3SAME_VQDMULH(VQRDMULH, qrdmulh)
 TCGv_ptr fpst = fpstatus_ptr(FPST); \
 tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, fpst,\
oprsz, maxsz, 0, FUNC);  \
-tcg_temp_free_ptr(fpst);\
 }
 
 #define DO_3S_FP_GVEC(INSN,SFUNC,HFUNC) \
@@ -1225,7 +1212,6 @@ static bool do_3same_fp_pair(DisasContext *s, arg_3same 
*a,
vfp_reg_offset(1, a->vn),
vfp_reg_offset(1, a->vm),
fpstatus, 8, 8, 0, fn);
-tcg_temp_free_ptr(fpstatus);
 
 return true;
 }
@@ -1358,7 +1344,6 @@ static bool do_2shift_env_64(DisasContext *s, 
arg_2reg_shift *a,
 read_neon_element64(tmp, a->vm, pass, MO_64);
 fn(tmp, cpu_env, tmp, constimm);
 write_neon_element64(tmp, a->vd, pass, MO_64);
-tcg_temp_free_i64(tmp);
 }
 return true;
 }
@@ -1403,7 +1388,6 @@ static bool do_2shift_env_32(DisasContext *s, 
arg_2reg_shift *a,
 fn(tmp, cpu_env, tmp, constimm);
 write_neon_element32(tmp, a->vd, pass, MO_32);
 }
-tcg_temp_free_i32(tmp);
 return true;
 }
 
@@ -1474,10 +1458,6 @@ static bool do_2shift_narrow_64(DisasContext *s, 
arg_2reg_shift *a,
 narrowfn(rd, cpu_env, rm2);
 write_neon_element32(rd, a->vd, 1, MO_32);
 
-tcg_temp_free_i32(rd);
-tcg_temp_free_i64(rm1);
-tcg_temp_free_i64(rm2);
-
 return true;
 }
 
@@ -1537,22 +1517,17 @@ static bool do_2shift_narrow_32(DisasContext *s, 
arg_2reg_shift *a,
 shiftfn(rm2, rm2, constimm);
 
 tcg_gen_concat_i32_i64(rtmp, rm1, rm2);
-tcg_temp_free_i32(rm2);
 
 narrowfn(rm1, cpu_env, rtmp);
 write_neon_element32(rm1, a->vd, 0, MO_32);
-tcg_temp_free_i32(rm1);
 
 shiftfn(rm3, rm3, constimm);
 shiftfn(rm4, rm4, constimm);
 
 tcg_gen_concat_i32_i64(rtmp, rm3, rm4);
-tcg_temp_free_i32(rm4);
 
 narrowfn(rm3, cpu_env, rtmp);
-tcg_temp_free_i64(rtmp);
 write_neon_element32(rm3, a->vd, 1, MO_32);
-tcg_temp_free_i32(rm3);
 return true;
 }
 
@@ -1660,7 +1635,6 @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift 
*a,
 tmp = tcg_temp_new_i64();
 
 widenfn(tmp, rm0);
-tcg_temp_free_i32(rm0);
 if (a->shift != 0) {
 tcg_gen_shli_i64(tmp, tmp, a->shift);
 tcg_gen_andi_i64(tmp, tmp, ~widen_mask

[PATCH v2 26/76] target/hexagon: Drop tcg_temp_free from gen_tcg_funcs.py

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries.

Signed-off-by: Richard Henderson 
---
 target/hexagon/gen_tcg_funcs.py | 79 +
 1 file changed, 1 insertion(+), 78 deletions(-)

diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index dfc90712fb..02cb52c21e 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -26,10 +26,7 @@
 ## Helpers for gen_tcg_func
 ##
 def gen_decl_ea_tcg(f, tag):
-f.write("TCGv EA = tcg_temp_new();\n")
-
-def gen_free_ea_tcg(f):
-f.write("tcg_temp_free(EA);\n")
+f.write("TCGv EA G_GNUC_UNUSED = tcg_temp_new();\n")
 
 def genptr_decl_pair_writable(f, tag, regtype, regid, regno):
 regN="%s%sN" % (regtype,regid)
@@ -269,73 +266,6 @@ def genptr_decl_imm(f,immlett):
 f.write("int %s = insn->immed[%d];\n" % \
 (hex_common.imm_name(immlett), i))
 
-def genptr_free(f, tag, regtype, regid, regno):
-if (regtype == "R"):
-if (regid in {"dd", "ss", "tt", "xx", "yy"}):
-f.write("tcg_temp_free_i64(%s%sV);\n" % (regtype, regid))
-elif (regid in {"d", "e", "x", "y"}):
-f.write("tcg_temp_free(%s%sV);\n" % (regtype, regid))
-elif (regid not in {"s", "t", "u", "v"}):
-print("Bad register parse: ",regtype,regid)
-elif (regtype == "P"):
-if (regid in {"d", "e", "x"}):
-f.write("tcg_temp_free(%s%sV);\n" % (regtype, regid))
-elif (regid not in {"s", "t", "u", "v"}):
-print("Bad register parse: ",regtype,regid)
-elif (regtype == "C"):
-if (regid in {"dd", "ss"}):
-f.write("tcg_temp_free_i64(%s%sV);\n" % (regtype, regid))
-elif (regid in {"d", "s"}):
-f.write("tcg_temp_free(%s%sV);\n" % (regtype, regid))
-else:
-print("Bad register parse: ",regtype,regid)
-elif (regtype == "M"):
-if (regid != "u"):
-print("Bad register parse: ", regtype, regid)
-elif (regtype == "V"):
-if (regid in {"dd", "uu", "vv", "xx", \
-  "d", "s", "u", "v", "w", "x", "y"}):
-if (not hex_common.skip_qemu_helper(tag)):
-f.write("tcg_temp_free_ptr(%s%sV);\n" % \
-(regtype, regid))
-else:
-print("Bad register parse: ", regtype, regid)
-elif (regtype == "Q"):
-if (regid in {"d", "e", "s", "t", "u", "v", "x"}):
-if (not hex_common.skip_qemu_helper(tag)):
-f.write("tcg_temp_free_ptr(%s%sV);\n" % \
-(regtype, regid))
-else:
-print("Bad register parse: ", regtype, regid)
-else:
-print("Bad register parse: ", regtype, regid)
-
-def genptr_free_new(f, tag, regtype, regid, regno):
-if (regtype == "N"):
-if (regid not in {"s", "t"}):
-print("Bad register parse: ", regtype, regid)
-elif (regtype == "P"):
-if (regid not in {"t", "u", "v"}):
-print("Bad register parse: ", regtype, regid)
-elif (regtype == "O"):
-if (regid != "s"):
-print("Bad register parse: ", regtype, regid)
-else:
-print("Bad register parse: ", regtype, regid)
-
-def genptr_free_opn(f,regtype,regid,i,tag):
-if (hex_common.is_pair(regid)):
-genptr_free(f, tag, regtype, regid, i)
-elif (hex_common.is_single(regid)):
-if hex_common.is_old_val(regtype, regid, tag):
-genptr_free(f, tag, regtype, regid, i)
-elif hex_common.is_new_val(regtype, regid, tag):
-genptr_free_new(f, tag, regtype, regid, i)
-else:
-print("Bad register parse: ",regtype,regid,toss,numregs)
-else:
-print("Bad register parse: ",regtype,regid,toss,numregs)
-
 def genptr_src_read(f, tag, regtype, regid):
 if (regtype == "R"):
 if (regid in {"ss", "tt", "xx", "yy"}):
@@ -578,7 +508,6 @@ def genptr_dst_write_opn(f,regtype, regid, tag):
 ##   
 ##   gen_log_reg_write(RdN, RdV);
 ##   ctx_log_reg_write(ctx, RdN);
-##   tcg_temp_free(RdV);
 ##   }
 ##
 ##   where  depends on hex_common.skip_qemu_helper(tag)
@@ -692,12 +621,6 @@ def gen_tcg_func(f, tag, regs, imms):
 if (hex_common.is_written(regid)):
 genptr_dst_write_opn(f,regtype, regid, tag)
 
-## Free all the operands (regs and immediates)
-if hex_common.need_ea(tag): gen_free_ea_tcg(f)
-for regtype,regid,toss,numregs in regs:
-genptr_free_opn(f,regtype,regid,i,tag)
-i += 1
-
 f.write("}\n\n")
 
 def gen_def_tcg_func(f, tag, tagregs, tagimms):
-- 
2.34.1




[PATCH v2 10/76] target/arm: Drop tcg_temp_free from translator-a64.c

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 468 +
 1 file changed, 11 insertions(+), 457 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index b5d6508cbc..b1fa210d64 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -542,7 +542,6 @@ static void write_fp_sreg(DisasContext *s, int reg, 
TCGv_i32 v)
 
 tcg_gen_extu_i32_i64(tmp, v);
 write_fp_dreg(s, reg, tmp);
-tcg_temp_free_i64(tmp);
 }
 
 /* Expand a 2-operand AdvSIMD vector operation using an expander function.  */
@@ -611,7 +610,6 @@ static void gen_gvec_op3_fpst(DisasContext *s, bool is_q, 
int rd, int rn,
vec_full_reg_offset(s, rn),
vec_full_reg_offset(s, rm), fpst,
is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
-tcg_temp_free_ptr(fpst);
 }
 
 /* Expand a 3-operand + qc + operation using an out-of-line helper.  */
@@ -625,7 +623,6 @@ static void gen_gvec_op3_qc(DisasContext *s, bool is_q, int 
rd, int rn,
vec_full_reg_offset(s, rn),
vec_full_reg_offset(s, rm), qc_ptr,
is_q ? 16 : 8, vec_full_reg_size(s), 0, fn);
-tcg_temp_free_ptr(qc_ptr);
 }
 
 /* Expand a 4-operand operation using an out-of-line helper.  */
@@ -653,7 +650,6 @@ static void gen_gvec_op4_fpst(DisasContext *s, bool is_q, 
int rd, int rn,
vec_full_reg_offset(s, rm),
vec_full_reg_offset(s, ra), fpst,
is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
-tcg_temp_free_ptr(fpst);
 }
 
 /* Set ZF and NF based on a 64 bit result. This is alas fiddlier
@@ -697,12 +693,9 @@ static void gen_add_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, 
TCGv_i64 t1)
 tcg_gen_xor_i64(flag, result, t0);
 tcg_gen_xor_i64(tmp, t0, t1);
 tcg_gen_andc_i64(flag, flag, tmp);
-tcg_temp_free_i64(tmp);
 tcg_gen_extrh_i64_i32(cpu_VF, flag);
 
 tcg_gen_mov_i64(dest, result);
-tcg_temp_free_i64(result);
-tcg_temp_free_i64(flag);
 } else {
 /* 32 bit arithmetic */
 TCGv_i32 t0_32 = tcg_temp_new_i32();
@@ -718,10 +711,6 @@ static void gen_add_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, 
TCGv_i64 t1)
 tcg_gen_xor_i32(tmp, t0_32, t1_32);
 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
 tcg_gen_extu_i32_i64(dest, cpu_NF);
-
-tcg_temp_free_i32(tmp);
-tcg_temp_free_i32(t0_32);
-tcg_temp_free_i32(t1_32);
 }
 }
 
@@ -745,11 +734,8 @@ static void gen_sub_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, 
TCGv_i64 t1)
 tmp = tcg_temp_new_i64();
 tcg_gen_xor_i64(tmp, t0, t1);
 tcg_gen_and_i64(flag, flag, tmp);
-tcg_temp_free_i64(tmp);
 tcg_gen_extrh_i64_i32(cpu_VF, flag);
 tcg_gen_mov_i64(dest, result);
-tcg_temp_free_i64(flag);
-tcg_temp_free_i64(result);
 } else {
 /* 32 bit arithmetic */
 TCGv_i32 t0_32 = tcg_temp_new_i32();
@@ -764,10 +750,7 @@ static void gen_sub_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, 
TCGv_i64 t1)
 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
 tmp = tcg_temp_new_i32();
 tcg_gen_xor_i32(tmp, t0_32, t1_32);
-tcg_temp_free_i32(t0_32);
-tcg_temp_free_i32(t1_32);
 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
-tcg_temp_free_i32(tmp);
 tcg_gen_extu_i32_i64(dest, cpu_NF);
 }
 }
@@ -779,7 +762,6 @@ static void gen_adc(int sf, TCGv_i64 dest, TCGv_i64 t0, 
TCGv_i64 t1)
 tcg_gen_extu_i32_i64(flag, cpu_CF);
 tcg_gen_add_i64(dest, t0, t1);
 tcg_gen_add_i64(dest, dest, flag);
-tcg_temp_free_i64(flag);
 
 if (!sf) {
 tcg_gen_ext32u_i64(dest, dest);
@@ -808,11 +790,6 @@ static void gen_adc_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, 
TCGv_i64 t1)
 tcg_gen_extrh_i64_i32(cpu_VF, vf_64);
 
 tcg_gen_mov_i64(dest, result);
-
-tcg_temp_free_i64(tmp);
-tcg_temp_free_i64(vf_64);
-tcg_temp_free_i64(cf_64);
-tcg_temp_free_i64(result);
 } else {
 TCGv_i32 t0_32 = tcg_temp_new_i32();
 TCGv_i32 t1_32 = tcg_temp_new_i32();
@@ -829,10 +806,6 @@ static void gen_adc_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, 
TCGv_i64 t1)
 tcg_gen_xor_i32(tmp, t0_32, t1_32);
 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
 tcg_gen_extu_i32_i64(dest, cpu_NF);
-
-tcg_temp_free_i32(tmp);
-tcg_temp_free_i32(t1_32);
-tcg_temp_free_i32(t0_32);
 }
 }
 
@@ -942,12 +915,7 @@ static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 
tcg_addr, int size)
 tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
 tcg_gen_qemu_st_i64(be ? tmplo : tmphi, tcg_hiaddr,
 get_mem_index(s), mop);
-
-tcg_temp_free_i64(tcg_hiaddr);
-tcg_temp_free_i64(tmphi);
 

[PATCH v2 08/76] target/arm: Drop new_tmp_a64

2023-02-26 Thread Richard Henderson
This is now a simple wrapper for tcg_temp_new_i64.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.h |  1 -
 target/arm/translate-a64.c | 45 +-
 target/arm/translate-sve.c | 20 -
 3 files changed, 30 insertions(+), 36 deletions(-)

diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
index ca24c39dbe..8ac126991f 100644
--- a/target/arm/translate-a64.h
+++ b/target/arm/translate-a64.h
@@ -18,7 +18,6 @@
 #ifndef TARGET_ARM_TRANSLATE_A64_H
 #define TARGET_ARM_TRANSLATE_A64_H
 
-TCGv_i64 new_tmp_a64(DisasContext *s);
 TCGv_i64 new_tmp_a64_zero(DisasContext *s);
 TCGv_i64 cpu_reg(DisasContext *s, int reg);
 TCGv_i64 cpu_reg_sp(DisasContext *s, int reg);
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 98d1bee5d5..04872d9925 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -224,7 +224,7 @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
 
 TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr)
 {
-TCGv_i64 clean = new_tmp_a64(s);
+TCGv_i64 clean = tcg_temp_new_i64();
 #ifdef CONFIG_USER_ONLY
 gen_top_byte_ignore(s, clean, addr, s->tbid);
 #else
@@ -269,7 +269,7 @@ static TCGv_i64 gen_mte_check1_mmuidx(DisasContext *s, 
TCGv_i64 addr,
 desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
 desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << log2_size) - 1);
 
-ret = new_tmp_a64(s);
+ret = tcg_temp_new_i64();
 gen_helper_mte_check(ret, cpu_env, tcg_constant_i32(desc), addr);
 
 return ret;
@@ -300,7 +300,7 @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, 
bool is_write,
 desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
 desc = FIELD_DP32(desc, MTEDESC, SIZEM1, size - 1);
 
-ret = new_tmp_a64(s);
+ret = tcg_temp_new_i64();
 gen_helper_mte_check(ret, cpu_env, tcg_constant_i32(desc), addr);
 
 return ret;
@@ -408,14 +408,9 @@ static void gen_goto_tb(DisasContext *s, int n, int64_t 
diff)
 }
 }
 
-TCGv_i64 new_tmp_a64(DisasContext *s)
-{
-return tcg_temp_new_i64();
-}
-
 TCGv_i64 new_tmp_a64_zero(DisasContext *s)
 {
-TCGv_i64 t = new_tmp_a64(s);
+TCGv_i64 t = tcg_temp_new_i64();
 tcg_gen_movi_i64(t, 0);
 return t;
 }
@@ -456,7 +451,7 @@ TCGv_i64 cpu_reg_sp(DisasContext *s, int reg)
  */
 TCGv_i64 read_cpu_reg(DisasContext *s, int reg, int sf)
 {
-TCGv_i64 v = new_tmp_a64(s);
+TCGv_i64 v = tcg_temp_new_i64();
 if (reg != 31) {
 if (sf) {
 tcg_gen_mov_i64(v, cpu_X[reg]);
@@ -471,7 +466,7 @@ TCGv_i64 read_cpu_reg(DisasContext *s, int reg, int sf)
 
 TCGv_i64 read_cpu_reg_sp(DisasContext *s, int reg, int sf)
 {
-TCGv_i64 v = new_tmp_a64(s);
+TCGv_i64 v = tcg_temp_new_i64();
 if (sf) {
 tcg_gen_mov_i64(v, cpu_X[reg]);
 } else {
@@ -1984,7 +1979,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, 
bool isread,
 desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
 desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
 
-tcg_rt = new_tmp_a64(s);
+tcg_rt = tcg_temp_new_i64();
 gen_helper_mte_check_zva(tcg_rt, cpu_env,
  tcg_constant_i32(desc), cpu_reg(s, rt));
 } else {
@@ -2293,7 +2288,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t 
insn)
 modifier = new_tmp_a64_zero(s);
 }
 if (s->pauth_active) {
-dst = new_tmp_a64(s);
+dst = tcg_temp_new_i64();
 if (op3 == 2) {
 gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
 } else {
@@ -2311,7 +2306,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t 
insn)
 if (opc == 1) {
 TCGv_i64 lr = cpu_reg(s, 30);
 if (dst == lr) {
-TCGv_i64 tmp = new_tmp_a64(s);
+TCGv_i64 tmp = tcg_temp_new_i64();
 tcg_gen_mov_i64(tmp, dst);
 dst = tmp;
 }
@@ -2330,7 +2325,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t 
insn)
 }
 btype_mod = opc & 1;
 if (s->pauth_active) {
-dst = new_tmp_a64(s);
+dst = tcg_temp_new_i64();
 modifier = cpu_reg_sp(s, op4);
 if (op3 == 2) {
 gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
@@ -2344,7 +2339,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t 
insn)
 if (opc == 9) {
 TCGv_i64 lr = cpu_reg(s, 30);
 if (dst == lr) {
-TCGv_i64 tmp = new_tmp_a64(s);
+TCGv_i64 tmp = tcg_temp_new_i64();
 tcg_gen_mov_i64(tmp, dst);
 dst = tmp;
 }
@@ -2912,7 +2907,7 @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
 
 tcg_rt = cpu_reg(s, rt);
 
-clean_

[PATCH v2 11/76] target/arm: Drop tcg_temp_free from translator-m-nocp.c

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-m-nocp.c | 20 
 1 file changed, 20 deletions(-)

diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c
index 5df7d46120..9a89aab785 100644
--- a/target/arm/translate-m-nocp.c
+++ b/target/arm/translate-m-nocp.c
@@ -91,7 +91,6 @@ static bool trans_VLLDM_VLSTM(DisasContext *s, 
arg_VLLDM_VLSTM *a)
 } else {
 gen_helper_v7m_vlstm(cpu_env, fptr);
 }
-tcg_temp_free_i32(fptr);
 
 clear_eci_state(s);
 
@@ -303,8 +302,6 @@ static void gen_branch_fpInactive(DisasContext *s, TCGCond 
cond,
 tcg_gen_andi_i32(fpca, fpca, R_V7M_CONTROL_FPCA_MASK);
 tcg_gen_or_i32(fpca, fpca, aspen);
 tcg_gen_brcondi_i32(tcg_invert_cond(cond), fpca, 0, label);
-tcg_temp_free_i32(aspen);
-tcg_temp_free_i32(fpca);
 }
 
 static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
@@ -328,7 +325,6 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int 
regno,
 case ARM_VFP_FPSCR:
 tmp = loadfn(s, opaque, true);
 gen_helper_vfp_set_fpscr(cpu_env, tmp);
-tcg_temp_free_i32(tmp);
 gen_lookup_tb(s);
 break;
 case ARM_VFP_FPSCR_NZCVQC:
@@ -351,7 +347,6 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int 
regno,
 tcg_gen_andi_i32(fpscr, fpscr, ~FPCR_NZCV_MASK);
 tcg_gen_or_i32(fpscr, fpscr, tmp);
 store_cpu_field(fpscr, vfp.xregs[ARM_VFP_FPSCR]);
-tcg_temp_free_i32(tmp);
 break;
 }
 case ARM_VFP_FPCXT_NS:
@@ -400,8 +395,6 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int 
regno,
 tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK);
 gen_helper_vfp_set_fpscr(cpu_env, tmp);
 s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
-tcg_temp_free_i32(tmp);
-tcg_temp_free_i32(sfpa);
 break;
 }
 case ARM_VFP_VPR:
@@ -423,7 +416,6 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int 
regno,
 R_V7M_VPR_P0_SHIFT, R_V7M_VPR_P0_LENGTH);
 store_cpu_field(vpr, v7m.vpr);
 s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
-tcg_temp_free_i32(tmp);
 break;
 }
 default:
@@ -491,7 +483,6 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
 tcg_gen_andi_i32(sfpa, control, R_V7M_CONTROL_SFPA_MASK);
 tcg_gen_shli_i32(sfpa, sfpa, 31 - R_V7M_CONTROL_SFPA_SHIFT);
 tcg_gen_or_i32(tmp, tmp, sfpa);
-tcg_temp_free_i32(sfpa);
 /*
  * Store result before updating FPSCR etc, in case
  * it is a memory write which causes an exception.
@@ -505,7 +496,6 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
 store_cpu_field(control, v7m.control[M_REG_S]);
 fpscr = load_cpu_field(v7m.fpdscr[M_REG_NS]);
 gen_helper_vfp_set_fpscr(cpu_env, fpscr);
-tcg_temp_free_i32(fpscr);
 lookup_tb = true;
 break;
 }
@@ -546,7 +536,6 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
 tcg_gen_andi_i32(sfpa, control, R_V7M_CONTROL_SFPA_MASK);
 tcg_gen_shli_i32(sfpa, sfpa, 31 - R_V7M_CONTROL_SFPA_SHIFT);
 tcg_gen_or_i32(tmp, tmp, sfpa);
-tcg_temp_free_i32(control);
 /* Store result before updating FPSCR, in case it faults */
 storefn(s, opaque, tmp, true);
 /* If SFPA is zero then set FPSCR from FPDSCR_NS */
@@ -554,9 +543,6 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
 tcg_gen_movcond_i32(TCG_COND_EQ, fpscr, sfpa, tcg_constant_i32(0),
 fpdscr, fpscr);
 gen_helper_vfp_set_fpscr(cpu_env, fpscr);
-tcg_temp_free_i32(sfpa);
-tcg_temp_free_i32(fpdscr);
-tcg_temp_free_i32(fpscr);
 break;
 }
 case ARM_VFP_VPR:
@@ -598,7 +584,6 @@ static void fp_sysreg_to_gpr(DisasContext *s, void *opaque, 
TCGv_i32 value,
 if (a->rt == 15) {
 /* Set the 4 flag bits in the CPSR */
 gen_set_nzcv(value);
-tcg_temp_free_i32(value);
 } else {
 store_reg(s, a->rt, value);
 }
@@ -666,7 +651,6 @@ static void fp_sysreg_to_memory(DisasContext *s, void 
*opaque, TCGv_i32 value,
 if (do_access) {
 gen_aa32_st_i32(s, value, addr, get_mem_index(s),
 MO_UL | MO_ALIGN | s->be_data);
-tcg_temp_free_i32(value);
 }
 
 if (a->w) {
@@ -675,8 +659,6 @@ static void fp_sysreg_to_memory(DisasContext *s, void 
*opaque, TCGv_i32 value,
 tcg_gen_addi_i32(addr, addr, offset);
 }
 store_reg(s, a->rn, addr);
-} else {
-tcg_temp_free_i32(addr);
 }
 }
 
@@ -717,8 +699,6 @@ static TCGv_i32 memory_to_fp_sysreg(DisasContext *s, void 
*opaque,
 tcg_gen_addi_i32(addr, addr, offset);
 }
 store_reg(s, a->rn, addr);
-} else {
-tcg_temp_free_i32(addr);
 }
 return value;
 }
-- 
2.3

[PATCH v2 18/76] target/avr: Drop DisasContext.free_skip_var0

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries,
therefore there's no need to record for later freeing.

Signed-off-by: Richard Henderson 
---
 target/avr/translate.c | 19 ---
 1 file changed, 19 deletions(-)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index e40d8e9681..e7f0e2bbe3 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -107,11 +107,6 @@ struct DisasContext {
  * tcg_gen_brcond_tl(skip_cond, skip_var0, skip_var1, skip_label);
  * }
  *
- * if (free_skip_var0) {
- * tcg_temp_free(skip_var0);
- * free_skip_var0 = false;
- * }
- *
  * translate(ctx);
  *
  * if (skip_label) {
@@ -121,7 +116,6 @@ struct DisasContext {
 TCGv skip_var0;
 TCGv skip_var1;
 TCGCond skip_cond;
-bool free_skip_var0;
 };
 
 void avr_cpu_tcg_init(void)
@@ -1375,7 +1369,6 @@ static bool trans_SBRC(DisasContext *ctx, arg_SBRC *a)
 
 ctx->skip_cond = TCG_COND_EQ;
 ctx->skip_var0 = tcg_temp_new();
-ctx->free_skip_var0 = true;
 
 tcg_gen_andi_tl(ctx->skip_var0, Rr, 1 << a->bit);
 return true;
@@ -1391,7 +1384,6 @@ static bool trans_SBRS(DisasContext *ctx, arg_SBRS *a)
 
 ctx->skip_cond = TCG_COND_NE;
 ctx->skip_var0 = tcg_temp_new();
-ctx->free_skip_var0 = true;
 
 tcg_gen_andi_tl(ctx->skip_var0, Rr, 1 << a->bit);
 return true;
@@ -1410,7 +1402,6 @@ static bool trans_SBIC(DisasContext *ctx, arg_SBIC *a)
 tcg_gen_andi_tl(temp, temp, 1 << a->bit);
 ctx->skip_cond = TCG_COND_EQ;
 ctx->skip_var0 = temp;
-ctx->free_skip_var0 = true;
 
 return true;
 }
@@ -1428,7 +1419,6 @@ static bool trans_SBIS(DisasContext *ctx, arg_SBIS *a)
 tcg_gen_andi_tl(temp, temp, 1 << a->bit);
 ctx->skip_cond = TCG_COND_NE;
 ctx->skip_var0 = temp;
-ctx->free_skip_var0 = true;
 
 return true;
 }
@@ -2886,10 +2876,6 @@ static bool canonicalize_skip(DisasContext *ctx)
 ctx->skip_cond = TCG_COND_NE;
 break;
 }
-if (ctx->free_skip_var0) {
-tcg_temp_free(ctx->skip_var0);
-ctx->free_skip_var0 = false;
-}
 ctx->skip_var0 = cpu_skip;
 return true;
 }
@@ -2944,7 +2930,6 @@ static void avr_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cs)
  * This ensures that cpu_skip is non-zero after the label
  * if and only if the skipped insn itself sets a skip.
  */
-ctx->free_skip_var0 = true;
 ctx->skip_var0 = tcg_temp_new();
 tcg_gen_mov_tl(ctx->skip_var0, cpu_skip);
 tcg_gen_movi_tl(cpu_skip, 0);
@@ -2956,10 +2941,6 @@ static void avr_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cs)
   ctx->skip_var1, skip_label);
 ctx->skip_var1 = NULL;
 }
-if (ctx->free_skip_var0) {
-tcg_temp_free(ctx->skip_var0);
-ctx->free_skip_var0 = false;
-}
 ctx->skip_cond = TCG_COND_NEVER;
 ctx->skip_var0 = NULL;
 }
-- 
2.34.1




[PATCH v2 34/76] target/m68k: Drop free_cond

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries.
Remove the g1 and g2 members of DisasCompare, as they were
used to track which temps needed to be freed.

Signed-off-by: Richard Henderson 
---
 target/m68k/translate.c | 40 
 1 file changed, 40 deletions(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index b3cd3e87e1..d7237b6a99 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -1249,8 +1249,6 @@ static int gen_ea_fp(CPUM68KState *env, DisasContext *s, 
uint16_t insn,
 
 typedef struct {
 TCGCond tcond;
-bool g1;
-bool g2;
 TCGv v1;
 TCGv v2;
 } DisasCompare;
@@ -1263,7 +1261,6 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, 
int cond)
 
 /* The CC_OP_CMP form can handle most normal comparisons directly.  */
 if (op == CC_OP_CMPB || op == CC_OP_CMPW || op == CC_OP_CMPL) {
-c->g1 = c->g2 = 1;
 c->v1 = QREG_CC_N;
 c->v2 = QREG_CC_V;
 switch (cond) {
@@ -1281,7 +1278,6 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, 
int cond)
 goto done;
 case 10: /* PL */
 case 11: /* MI */
-c->g1 = c->g2 = 0;
 c->v2 = tcg_const_i32(0);
 c->v1 = tmp = tcg_temp_new();
 tcg_gen_sub_i32(tmp, QREG_CC_N, QREG_CC_V);
@@ -1298,8 +1294,6 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, 
int cond)
 }
 }
 
-c->g1 = 1;
-c->g2 = 0;
 c->v2 = tcg_const_i32(0);
 
 switch (cond) {
@@ -1383,7 +1377,6 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, 
int cond)
 case 2: /* HI (!C && !Z) -> !(C || Z)*/
 case 3: /* LS (C || Z) */
 c->v1 = tmp = tcg_temp_new();
-c->g1 = 0;
 tcg_gen_setcond_i32(TCG_COND_EQ, tmp, QREG_CC_Z, c->v2);
 tcg_gen_or_i32(tmp, tmp, QREG_CC_C);
 tcond = TCG_COND_NE;
@@ -1411,14 +1404,12 @@ static void gen_cc_cond(DisasCompare *c, DisasContext 
*s, int cond)
 case 12: /* GE (!(N ^ V)) */
 case 13: /* LT (N ^ V) */
 c->v1 = tmp = tcg_temp_new();
-c->g1 = 0;
 tcg_gen_xor_i32(tmp, QREG_CC_N, QREG_CC_V);
 tcond = TCG_COND_LT;
 break;
 case 14: /* GT (!(Z || (N ^ V))) */
 case 15: /* LE (Z || (N ^ V)) */
 c->v1 = tmp = tcg_temp_new();
-c->g1 = 0;
 tcg_gen_setcond_i32(TCG_COND_EQ, tmp, QREG_CC_Z, c->v2);
 tcg_gen_neg_i32(tmp, tmp);
 tmp2 = tcg_temp_new();
@@ -1436,16 +1427,6 @@ static void gen_cc_cond(DisasCompare *c, DisasContext 
*s, int cond)
 c->tcond = tcond;
 }
 
-static void free_cond(DisasCompare *c)
-{
-if (!c->g1) {
-tcg_temp_free(c->v1);
-}
-if (!c->g2) {
-tcg_temp_free(c->v2);
-}
-}
-
 static void gen_jmpcc(DisasContext *s, int cond, TCGLabel *l1)
 {
   DisasCompare c;
@@ -1453,7 +1434,6 @@ static void gen_jmpcc(DisasContext *s, int cond, TCGLabel 
*l1)
   gen_cc_cond(&c, s, cond);
   update_cc_op(s);
   tcg_gen_brcond_i32(c.tcond, c.v1, c.v2, l1);
-  free_cond(&c);
 }
 
 /* Force a TB lookup after an instruction that changes the CPU state.  */
@@ -1512,7 +1492,6 @@ DISAS_INSN(scc)
 
 tmp = tcg_temp_new();
 tcg_gen_setcond_i32(c.tcond, tmp, c.v1, c.v2);
-free_cond(&c);
 
 tcg_gen_neg_i32(tmp, tmp);
 DEST_EA(env, insn, OS_BYTE, tmp, NULL);
@@ -4887,7 +4866,6 @@ static void do_trapcc(DisasContext *s, DisasCompare *c)
 s->base.is_jmp = DISAS_NEXT;
 }
 }
-free_cond(c);
 }
 
 DISAS_INSN(trapcc)
@@ -5383,9 +5361,7 @@ static void gen_fcc_cond(DisasCompare *c, DisasContext 
*s, int cond)
 {
 TCGv fpsr;
 
-c->g1 = 1;
 c->v2 = tcg_const_i32(0);
-c->g2 = 0;
 /* TODO: Raise BSUN exception.  */
 fpsr = tcg_temp_new();
 gen_load_fcr(s, fpsr, M68K_FPSR);
@@ -5398,14 +5374,12 @@ static void gen_fcc_cond(DisasCompare *c, DisasContext 
*s, int cond)
 case 1:  /* EQual Z */
 case 17: /* Signaling EQual Z */
 c->v1 = tcg_temp_new();
-c->g1 = 0;
 tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
 c->tcond = TCG_COND_NE;
 break;
 case 2:  /* Ordered Greater Than !(A || Z || N) */
 case 18: /* Greater Than !(A || Z || N) */
 c->v1 = tcg_temp_new();
-c->g1 = 0;
 tcg_gen_andi_i32(c->v1, fpsr,
  FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
 c->tcond = TCG_COND_EQ;
@@ -5413,7 +5387,6 @@ static void gen_fcc_cond(DisasCompare *c, DisasContext 
*s, int cond)
 case 3:  /* Ordered Greater than or Equal Z || !(A || N) */
 case 19: /* Greater than or Equal Z || !(A || N) */
 c->v1 = tcg_temp_new();
-c->g1 = 0;
 tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
 tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_A));
 tcg_gen_andi_i32(fpsr, fpsr, FPSR_CC_Z | FPSR_CC_N);
@@ -5424,7 +5397,6 @@ static void gen_fcc_cond(DisasCompare *c, DisasContext 
*s, int con

[PATCH v2 31/76] target/loongarch: Drop temp_new

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries,
therefore there's no need to record temps for later freeing.
Replace the few uses with tcg_temp_new.

Reviewed-by: Song Gao 
Signed-off-by: Richard Henderson 
---
 target/loongarch/translate.h  |  3 ---
 target/loongarch/translate.c  | 21 +++
 .../insn_trans/trans_privileged.c.inc |  2 +-
 3 files changed, 4 insertions(+), 22 deletions(-)

diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
index 6d2e382e8b..67bc74c05b 100644
--- a/target/loongarch/translate.h
+++ b/target/loongarch/translate.h
@@ -32,9 +32,6 @@ typedef struct DisasContext {
 uint16_t mem_idx;
 uint16_t plv;
 TCGv zero;
-/* Space for 3 operands plus 1 extra for address computation. */
-TCGv temp[4];
-uint8_t ntemp;
 } DisasContext;
 
 void generate_exception(DisasContext *ctx, int excp);
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 2a43ab0201..f443b5822f 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -85,9 +85,6 @@ static void loongarch_tr_init_disas_context(DisasContextBase 
*dcbase,
 bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
 ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
 
-ctx->ntemp = 0;
-memset(ctx->temp, 0, sizeof(ctx->temp));
-
 ctx->zero = tcg_constant_tl(0);
 }
 
@@ -110,12 +107,6 @@ static void loongarch_tr_insn_start(DisasContextBase 
*dcbase, CPUState *cs)
  *
  * Further, we may provide an extension for word operations.
  */
-static TCGv temp_new(DisasContext *ctx)
-{
-assert(ctx->ntemp < ARRAY_SIZE(ctx->temp));
-return ctx->temp[ctx->ntemp++] = tcg_temp_new();
-}
-
 static TCGv gpr_src(DisasContext *ctx, int reg_num, DisasExtend src_ext)
 {
 TCGv t;
@@ -128,11 +119,11 @@ static TCGv gpr_src(DisasContext *ctx, int reg_num, 
DisasExtend src_ext)
 case EXT_NONE:
 return cpu_gpr[reg_num];
 case EXT_SIGN:
-t = temp_new(ctx);
+t = tcg_temp_new();
 tcg_gen_ext32s_tl(t, cpu_gpr[reg_num]);
 return t;
 case EXT_ZERO:
-t = temp_new(ctx);
+t = tcg_temp_new();
 tcg_gen_ext32u_tl(t, cpu_gpr[reg_num]);
 return t;
 }
@@ -142,7 +133,7 @@ static TCGv gpr_src(DisasContext *ctx, int reg_num, 
DisasExtend src_ext)
 static TCGv gpr_dst(DisasContext *ctx, int reg_num, DisasExtend dst_ext)
 {
 if (reg_num == 0 || dst_ext) {
-return temp_new(ctx);
+return tcg_temp_new();
 }
 return cpu_gpr[reg_num];
 }
@@ -195,12 +186,6 @@ static void loongarch_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cs)
 generate_exception(ctx, EXCCODE_INE);
 }
 
-for (int i = ctx->ntemp - 1; i >= 0; --i) {
-tcg_temp_free(ctx->temp[i]);
-ctx->temp[i] = NULL;
-}
-ctx->ntemp = 0;
-
 ctx->base.pc_next += 4;
 }
 
diff --git a/target/loongarch/insn_trans/trans_privileged.c.inc 
b/target/loongarch/insn_trans/trans_privileged.c.inc
index 40f82becb0..56f4c45e09 100644
--- a/target/loongarch/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/insn_trans/trans_privileged.c.inc
@@ -243,7 +243,7 @@ static bool trans_csrwr(DisasContext *ctx, arg_csrwr *a)
 dest = gpr_dst(ctx, a->rd, EXT_NONE);
 csr->writefn(dest, cpu_env, src1);
 } else {
-dest = temp_new(ctx);
+dest = tcg_temp_new();
 tcg_gen_ld_tl(dest, cpu_env, csr->offset);
 tcg_gen_st_tl(src1, cpu_env, csr->offset);
 }
-- 
2.34.1




[PATCH v2 02/76] accel/tcg: Remove translator_loop_temp_check

2023-02-26 Thread Richard Henderson
Finish removing tcg temp free accounting interfaces.

Signed-off-by: Richard Henderson 
---
 include/exec/translator.h  | 2 --
 accel/tcg/translator.c | 4 
 target/alpha/translate.c   | 1 -
 target/arm/translate-a64.c | 2 --
 target/arm/translate.c | 1 -
 target/ppc/translate.c | 2 --
 6 files changed, 12 deletions(-)

diff --git a/include/exec/translator.h b/include/exec/translator.h
index 8b36690e80..797fef7515 100644
--- a/include/exec/translator.h
+++ b/include/exec/translator.h
@@ -150,8 +150,6 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, 
int *max_insns,
  target_ulong pc, void *host_pc,
  const TranslatorOps *ops, DisasContextBase *db);
 
-void translator_loop_temp_check(DisasContextBase *db);
-
 /**
  * translator_use_goto_tb
  * @db: Disassembly context
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
index 88567a88d1..b4183d0278 100644
--- a/accel/tcg/translator.c
+++ b/accel/tcg/translator.c
@@ -18,10 +18,6 @@
 #include "exec/plugin-gen.h"
 #include "sysemu/replay.h"
 
-void translator_loop_temp_check(DisasContextBase *db)
-{
-}
-
 bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest)
 {
 /* Suppress goto_tb if requested. */
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 716b083f39..a0afdbb465 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -2996,7 +2996,6 @@ static void alpha_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
 ctx->base.is_jmp = translate_one(ctx, insn);
 
 free_context_temps(ctx);
-translator_loop_temp_check(&ctx->base);
 }
 
 static void alpha_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 9da5010fe1..98537bc2ef 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -14957,8 +14957,6 @@ static void aarch64_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
 if (s->btype > 0 && s->base.is_jmp != DISAS_NORETURN) {
 reset_btype(s);
 }
-
-translator_loop_temp_check(&s->base);
 }
 
 static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 9c8e1ac04c..614c438786 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -9600,7 +9600,6 @@ static void arm_post_translate_insn(DisasContext *dc)
 gen_set_label(dc->condlabel.label);
 dc->condjmp = 0;
 }
-translator_loop_temp_check(&dc->base);
 }
 
 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 2956021e89..c179f26f64 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7618,8 +7618,6 @@ static void ppc_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cs)
 if (ctx->base.is_jmp == DISAS_NEXT && !(pc & ~TARGET_PAGE_MASK)) {
 ctx->base.is_jmp = DISAS_TOO_MANY;
 }
-
-translator_loop_temp_check(&ctx->base);
 }
 
 static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
-- 
2.34.1




[PATCH v2 12/76] target/arm: Drop tcg_temp_free from translator-mve.c

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-mve.c | 52 --
 1 file changed, 52 deletions(-)

diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
index db7ea3f603..798b4fddfe 100644
--- a/target/arm/translate-mve.c
+++ b/target/arm/translate-mve.c
@@ -178,7 +178,6 @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, 
MVEGenLdStFn *fn,
 
 qreg = mve_qreg_ptr(a->qd);
 fn(cpu_env, qreg, addr);
-tcg_temp_free_ptr(qreg);
 
 /*
  * Writeback always happens after the last beat of the insn,
@@ -189,8 +188,6 @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, 
MVEGenLdStFn *fn,
 tcg_gen_addi_i32(addr, addr, offset);
 }
 store_reg(s, a->rn, addr);
-} else {
-tcg_temp_free_i32(addr);
 }
 mve_update_eci(s);
 return true;
@@ -242,9 +239,6 @@ static bool do_ldst_sg(DisasContext *s, arg_vldst_sg *a, 
MVEGenLdStSGFn fn)
 qd = mve_qreg_ptr(a->qd);
 qm = mve_qreg_ptr(a->qm);
 fn(cpu_env, qd, qm, addr);
-tcg_temp_free_ptr(qd);
-tcg_temp_free_ptr(qm);
-tcg_temp_free_i32(addr);
 mve_update_eci(s);
 return true;
 }
@@ -341,8 +335,6 @@ static bool do_ldst_sg_imm(DisasContext *s, 
arg_vldst_sg_imm *a,
 qd = mve_qreg_ptr(a->qd);
 qm = mve_qreg_ptr(a->qm);
 fn(cpu_env, qd, qm, tcg_constant_i32(offset));
-tcg_temp_free_ptr(qd);
-tcg_temp_free_ptr(qm);
 mve_update_eci(s);
 return true;
 }
@@ -414,8 +406,6 @@ static bool do_vldst_il(DisasContext *s, arg_vldst_il *a, 
MVEGenLdStIlFn *fn,
 if (a->w) {
 tcg_gen_addi_i32(rn, rn, addrinc);
 store_reg(s, a->rn, rn);
-} else {
-tcg_temp_free_i32(rn);
 }
 mve_update_and_store_eci(s);
 return true;
@@ -506,9 +496,7 @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
 qd = mve_qreg_ptr(a->qd);
 tcg_gen_dup_i32(a->size, rt, rt);
 gen_helper_mve_vdup(cpu_env, qd, rt);
-tcg_temp_free_ptr(qd);
 }
-tcg_temp_free_i32(rt);
 mve_update_eci(s);
 return true;
 }
@@ -534,8 +522,6 @@ static bool do_1op_vec(DisasContext *s, arg_1op *a, 
MVEGenOneOpFn fn,
 qd = mve_qreg_ptr(a->qd);
 qm = mve_qreg_ptr(a->qm);
 fn(cpu_env, qd, qm);
-tcg_temp_free_ptr(qd);
-tcg_temp_free_ptr(qm);
 }
 mve_update_eci(s);
 return true;
@@ -631,8 +617,6 @@ static bool do_vcvt_rmode(DisasContext *s, arg_1op *a,
 qd = mve_qreg_ptr(a->qd);
 qm = mve_qreg_ptr(a->qm);
 fn(cpu_env, qd, qm, tcg_constant_i32(arm_rmode_to_sf(rmode)));
-tcg_temp_free_ptr(qd);
-tcg_temp_free_ptr(qm);
 mve_update_eci(s);
 return true;
 }
@@ -821,9 +805,6 @@ static bool do_2op_vec(DisasContext *s, arg_2op *a, 
MVEGenTwoOpFn fn,
 qn = mve_qreg_ptr(a->qn);
 qm = mve_qreg_ptr(a->qm);
 fn(cpu_env, qd, qn, qm);
-tcg_temp_free_ptr(qd);
-tcg_temp_free_ptr(qn);
-tcg_temp_free_ptr(qm);
 }
 mve_update_eci(s);
 return true;
@@ -1076,9 +1057,6 @@ static bool do_2op_scalar(DisasContext *s, arg_2scalar *a,
 qn = mve_qreg_ptr(a->qn);
 rm = load_reg(s, a->rm);
 fn(cpu_env, qd, qn, rm);
-tcg_temp_free_i32(rm);
-tcg_temp_free_ptr(qd);
-tcg_temp_free_ptr(qn);
 mve_update_eci(s);
 return true;
 }
@@ -1204,15 +1182,11 @@ static bool do_long_dual_acc(DisasContext *s, 
arg_vmlaldav *a,
 rdalo = load_reg(s, a->rdalo);
 rdahi = load_reg(s, a->rdahi);
 tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
-tcg_temp_free_i32(rdalo);
-tcg_temp_free_i32(rdahi);
 } else {
 rda = tcg_const_i64(0);
 }
 
 fn(rda, cpu_env, qn, qm, rda);
-tcg_temp_free_ptr(qn);
-tcg_temp_free_ptr(qm);
 
 rdalo = tcg_temp_new_i32();
 rdahi = tcg_temp_new_i32();
@@ -1220,7 +1194,6 @@ static bool do_long_dual_acc(DisasContext *s, 
arg_vmlaldav *a,
 tcg_gen_extrh_i64_i32(rdahi, rda);
 store_reg(s, a->rdalo, rdalo);
 store_reg(s, a->rdahi, rdahi);
-tcg_temp_free_i64(rda);
 mve_update_eci(s);
 return true;
 }
@@ -1312,8 +1285,6 @@ static bool do_dual_acc(DisasContext *s, arg_vmladav *a, 
MVEGenDualAccOpFn *fn)
 
 fn(rda, cpu_env, qn, qm, rda);
 store_reg(s, a->rda, rda);
-tcg_temp_free_ptr(qn);
-tcg_temp_free_ptr(qm);
 
 mve_update_eci(s);
 return true;
@@ -1451,7 +1422,6 @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
 qm = mve_qreg_ptr(a->qm);
 fns[a->size][a->u](rda, cpu_env, qm, rda);
 store_reg(s, a->rda, rda);
-tcg_temp_free_ptr(qm);
 
 mve_update_eci(s);
 return true;
@@ -1494,8 +1464,6 @@ static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
 rdalo = load_reg(s, a->rdalo);
 rdahi = load_reg(s, a->rdahi);
 tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
-tcg_temp_free_i32(rdalo);
-tcg_temp_free_i32(rd

[PATCH v2 05/76] target/arm: Remove value_global from DisasCompare

2023-02-26 Thread Richard Henderson
This field was only used to avoid freeing globals.
Since we no longer free any temps, this is dead.

Signed-off-by: Richard Henderson 
---
 target/arm/translate.h | 1 -
 target/arm/translate.c | 5 -
 2 files changed, 6 deletions(-)

diff --git a/target/arm/translate.h b/target/arm/translate.h
index 7f52f08c5e..db29e8d799 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -157,7 +157,6 @@ typedef struct DisasContext {
 typedef struct DisasCompare {
 TCGCond cond;
 TCGv_i32 value;
-bool value_global;
 } DisasCompare;
 
 /* Share the TCG temporaries common between 32 and 64 bit modes.  */
diff --git a/target/arm/translate.c b/target/arm/translate.c
index a0a298f8f7..f76a83b473 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -672,7 +672,6 @@ void arm_test_cc(DisasCompare *cmp, int cc)
 {
 TCGv_i32 value;
 TCGCond cond;
-bool global = true;
 
 switch (cc) {
 case 0: /* eq: Z */
@@ -703,7 +702,6 @@ void arm_test_cc(DisasCompare *cmp, int cc)
 case 9: /* ls: !C || Z -> !(C && !Z) */
 cond = TCG_COND_NE;
 value = tcg_temp_new_i32();
-global = false;
 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
ZF is non-zero for !Z; so AND the two subexpressions.  */
 tcg_gen_neg_i32(value, cpu_CF);
@@ -715,7 +713,6 @@ void arm_test_cc(DisasCompare *cmp, int cc)
 /* Since we're only interested in the sign bit, == 0 is >= 0.  */
 cond = TCG_COND_GE;
 value = tcg_temp_new_i32();
-global = false;
 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
 break;
 
@@ -723,7 +720,6 @@ void arm_test_cc(DisasCompare *cmp, int cc)
 case 13: /* le: Z || N != V */
 cond = TCG_COND_NE;
 value = tcg_temp_new_i32();
-global = false;
 /* (N == V) is equal to the sign bit of ~(NF ^ VF).  Propagate
  * the sign bit then AND with ZF to yield the result.  */
 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
@@ -751,7 +747,6 @@ void arm_test_cc(DisasCompare *cmp, int cc)
  no_invert:
 cmp->cond = cond;
 cmp->value = value;
-cmp->value_global = global;
 }
 
 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
-- 
2.34.1




[PATCH v2 38/76] target/mips: Drop tcg_temp_free from mips16e_translate.c.inc

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries.

Signed-off-by: Richard Henderson 
---
 target/mips/tcg/mips16e_translate.c.inc | 6 --
 1 file changed, 6 deletions(-)

diff --git a/target/mips/tcg/mips16e_translate.c.inc 
b/target/mips/tcg/mips16e_translate.c.inc
index 918b15d55c..602f5f0c02 100644
--- a/target/mips/tcg/mips16e_translate.c.inc
+++ b/target/mips/tcg/mips16e_translate.c.inc
@@ -280,9 +280,6 @@ static void gen_mips16_save(DisasContext *ctx,
 
 tcg_gen_movi_tl(t2, -framesize);
 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
-tcg_temp_free(t0);
-tcg_temp_free(t1);
-tcg_temp_free(t2);
 }
 
 static void gen_mips16_restore(DisasContext *ctx,
@@ -386,9 +383,6 @@ static void gen_mips16_restore(DisasContext *ctx,
 
 tcg_gen_movi_tl(t2, framesize);
 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
-tcg_temp_free(t0);
-tcg_temp_free(t1);
-tcg_temp_free(t2);
 }
 
 #if defined(TARGET_MIPS64)
-- 
2.34.1




[PATCH v2 03/76] target/alpha: Drop tcg_temp_free

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries.

Signed-off-by: Richard Henderson 
---
 target/alpha/translate.c | 70 
 1 file changed, 70 deletions(-)

diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index a0afdbb465..9d25e21164 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -179,7 +179,6 @@ static void free_context_temps(DisasContext *ctx)
 {
 if (ctx->sink) {
 tcg_gen_discard_i64(ctx->sink);
-tcg_temp_free(ctx->sink);
 ctx->sink = NULL;
 }
 }
@@ -279,7 +278,6 @@ static void gen_ldf(DisasContext *ctx, TCGv dest, TCGv addr)
 TCGv_i32 tmp32 = tcg_temp_new_i32();
 tcg_gen_qemu_ld_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx));
 gen_helper_memory_to_f(dest, tmp32);
-tcg_temp_free_i32(tmp32);
 }
 
 static void gen_ldg(DisasContext *ctx, TCGv dest, TCGv addr)
@@ -287,7 +285,6 @@ static void gen_ldg(DisasContext *ctx, TCGv dest, TCGv addr)
 TCGv tmp = tcg_temp_new();
 tcg_gen_qemu_ld_i64(tmp, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx));
 gen_helper_memory_to_g(dest, tmp);
-tcg_temp_free(tmp);
 }
 
 static void gen_lds(DisasContext *ctx, TCGv dest, TCGv addr)
@@ -295,7 +292,6 @@ static void gen_lds(DisasContext *ctx, TCGv dest, TCGv addr)
 TCGv_i32 tmp32 = tcg_temp_new_i32();
 tcg_gen_qemu_ld_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx));
 gen_helper_memory_to_s(dest, tmp32);
-tcg_temp_free_i32(tmp32);
 }
 
 static void gen_ldt(DisasContext *ctx, TCGv dest, TCGv addr)
@@ -311,7 +307,6 @@ static void gen_load_fp(DisasContext *ctx, int ra, int rb, 
int32_t disp16,
 TCGv addr = tcg_temp_new();
 tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
 func(ctx, cpu_fir[ra], addr);
-tcg_temp_free(addr);
 }
 }
 
@@ -342,7 +337,6 @@ static void gen_load_int(DisasContext *ctx, int ra, int rb, 
int32_t disp16,
 tcg_gen_mov_i64(cpu_lock_addr, addr);
 tcg_gen_mov_i64(cpu_lock_value, dest);
 }
-tcg_temp_free(addr);
 }
 
 static void gen_stf(DisasContext *ctx, TCGv src, TCGv addr)
@@ -350,7 +344,6 @@ static void gen_stf(DisasContext *ctx, TCGv src, TCGv addr)
 TCGv_i32 tmp32 = tcg_temp_new_i32();
 gen_helper_f_to_memory(tmp32, addr);
 tcg_gen_qemu_st_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx));
-tcg_temp_free_i32(tmp32);
 }
 
 static void gen_stg(DisasContext *ctx, TCGv src, TCGv addr)
@@ -358,7 +351,6 @@ static void gen_stg(DisasContext *ctx, TCGv src, TCGv addr)
 TCGv tmp = tcg_temp_new();
 gen_helper_g_to_memory(tmp, src);
 tcg_gen_qemu_st_i64(tmp, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx));
-tcg_temp_free(tmp);
 }
 
 static void gen_sts(DisasContext *ctx, TCGv src, TCGv addr)
@@ -366,7 +358,6 @@ static void gen_sts(DisasContext *ctx, TCGv src, TCGv addr)
 TCGv_i32 tmp32 = tcg_temp_new_i32();
 gen_helper_s_to_memory(tmp32, src);
 tcg_gen_qemu_st_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx));
-tcg_temp_free_i32(tmp32);
 }
 
 static void gen_stt(DisasContext *ctx, TCGv src, TCGv addr)
@@ -380,7 +371,6 @@ static void gen_store_fp(DisasContext *ctx, int ra, int rb, 
int32_t disp16,
 TCGv addr = tcg_temp_new();
 tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
 func(ctx, load_fpr(ctx, ra), addr);
-tcg_temp_free(addr);
 }
 
 static void gen_store_int(DisasContext *ctx, int ra, int rb, int32_t disp16,
@@ -398,8 +388,6 @@ static void gen_store_int(DisasContext *ctx, int ra, int 
rb, int32_t disp16,
 
 src = load_gpr(ctx, ra);
 tcg_gen_qemu_st_i64(src, addr, ctx->mem_idx, op);
-
-tcg_temp_free(addr);
 }
 
 static DisasJumpType gen_store_conditional(DisasContext *ctx, int ra, int rb,
@@ -416,7 +404,6 @@ static DisasJumpType gen_store_conditional(DisasContext 
*ctx, int ra, int rb,
 lab_fail = gen_new_label();
 lab_done = gen_new_label();
 tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail);
-tcg_temp_free_i64(addr);
 
 val = tcg_temp_new_i64();
 tcg_gen_atomic_cmpxchg_i64(val, cpu_lock_addr, cpu_lock_value,
@@ -426,7 +413,6 @@ static DisasJumpType gen_store_conditional(DisasContext 
*ctx, int ra, int rb,
 if (ra != 31) {
 tcg_gen_setcond_i64(TCG_COND_EQ, ctx->ir[ra], val, cpu_lock_value);
 }
-tcg_temp_free_i64(val);
 tcg_gen_br(lab_done);
 
 gen_set_label(lab_fail);
@@ -504,7 +490,6 @@ static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond 
cond, int ra,
 
 tcg_gen_andi_i64(tmp, load_gpr(ctx, ra), 1);
 ret = gen_bcond_internal(ctx, cond, tmp, disp);
-tcg_temp_free(tmp);
 return ret;
 }
 return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra), disp);
@@ -550,7 +535,6 @@ static DisasJumpType gen_fbcond(DisasContext *ctx, TCGCond 
cond, int ra,
 
 gen_fold_mzero(cond, cmp_tmp, load_fpr(ctx, ra));
 ret = gen_bcond_internal(ctx, cond, cmp_tmp, disp);
-tcg_temp_free(cmp_tmp);
 ret

[PATCH v2 39/76] target/mips: Drop tcg_temp_free from msa_translate.c

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries.

Signed-off-by: Richard Henderson 
---
 target/mips/tcg/msa_translate.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/target/mips/tcg/msa_translate.c b/target/mips/tcg/msa_translate.c
index 1bcdbb1121..220cd3b048 100644
--- a/target/mips/tcg/msa_translate.c
+++ b/target/mips/tcg/msa_translate.c
@@ -217,8 +217,6 @@ static void gen_check_zero_element(TCGv tresult, uint8_t 
df, uint8_t wt,
 /* if some bit is non-zero then some element is zero */
 tcg_gen_setcondi_i64(cond, t0, t0, 0);
 tcg_gen_trunc_i64_tl(tresult, t0);
-tcg_temp_free_i64(t0);
-tcg_temp_free_i64(t1);
 }
 
 static bool gen_msa_BxZ_V(DisasContext *ctx, int wt, int sa, TCGCond cond)
@@ -237,7 +235,6 @@ static bool gen_msa_BxZ_V(DisasContext *ctx, int wt, int 
sa, TCGCond cond)
 tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]);
 tcg_gen_setcondi_i64(cond, t0, t0, 0);
 tcg_gen_trunc_i64_tl(bcond, t0);
-tcg_temp_free_i64(t0);
 
 ctx->btarget = ctx->base.pc_next + (sa << 2) + 4;
 
@@ -545,8 +542,6 @@ static bool trans_CTCMSA(DisasContext *ctx, arg_msa_elm *a)
 gen_load_gpr(telm, a->ws);
 gen_helper_msa_ctcmsa(cpu_env, telm, tcg_constant_i32(a->wd));
 
-tcg_temp_free(telm);
-
 return true;
 }
 
@@ -563,8 +558,6 @@ static bool trans_CFCMSA(DisasContext *ctx, arg_msa_elm *a)
 gen_helper_msa_cfcmsa(telm, cpu_env, tcg_constant_i32(a->ws));
 gen_store_gpr(telm, a->wd);
 
-tcg_temp_free(telm);
-
 return true;
 }
 
@@ -782,8 +775,6 @@ static bool trans_msa_ldst(DisasContext *ctx, arg_msa_i *a,
 gen_base_offset_addr(ctx, taddr, a->ws, a->sa << a->df);
 gen_msa_ldst(cpu_env, tcg_constant_i32(a->wd), taddr);
 
-tcg_temp_free(taddr);
-
 return true;
 }
 
-- 
2.34.1




[PATCH v2 33/76] target/m68k: Drop mark_to_release

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries,
therefore there's no need to record temps for later freeing.

Signed-off-by: Richard Henderson 
---
 target/m68k/translate.c | 55 ++---
 1 file changed, 13 insertions(+), 42 deletions(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 157c2cbb8f..b3cd3e87e1 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -121,35 +121,9 @@ typedef struct DisasContext {
 int done_mac;
 int writeback_mask;
 TCGv writeback[8];
-#define MAX_TO_RELEASE 8
-int release_count;
-TCGv release[MAX_TO_RELEASE];
 bool ss_active;
 } DisasContext;
 
-static void init_release_array(DisasContext *s)
-{
-#ifdef CONFIG_DEBUG_TCG
-memset(s->release, 0, sizeof(s->release));
-#endif
-s->release_count = 0;
-}
-
-static void do_release(DisasContext *s)
-{
-int i;
-for (i = 0; i < s->release_count; i++) {
-tcg_temp_free(s->release[i]);
-}
-init_release_array(s);
-}
-
-static TCGv mark_to_release(DisasContext *s, TCGv tmp)
-{
-g_assert(s->release_count < MAX_TO_RELEASE);
-return s->release[s->release_count++] = tmp;
-}
-
 static TCGv get_areg(DisasContext *s, unsigned regno)
 {
 if (s->writeback_mask & (1 << regno)) {
@@ -396,8 +370,7 @@ static TCGv gen_ldst(DisasContext *s, int opsize, TCGv 
addr, TCGv val,
 gen_store(s, opsize, addr, val, index);
 return store_dummy;
 } else {
-return mark_to_release(s, gen_load(s, opsize, addr,
-   what == EA_LOADS, index));
+return gen_load(s, opsize, addr, what == EA_LOADS, index);
 }
 }
 
@@ -491,7 +464,7 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext 
*s, TCGv base)
 } else {
 bd = 0;
 }
-tmp = mark_to_release(s, tcg_temp_new());
+tmp = tcg_temp_new();
 if ((ext & 0x44) == 0) {
 /* pre-index */
 add = gen_addr_index(s, ext, tmp);
@@ -501,7 +474,7 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext 
*s, TCGv base)
 if ((ext & 0x80) == 0) {
 /* base not suppressed */
 if (IS_NULL_QREG(base)) {
-base = mark_to_release(s, tcg_const_i32(offset + bd));
+base = tcg_const_i32(offset + bd);
 bd = 0;
 }
 if (!IS_NULL_QREG(add)) {
@@ -517,11 +490,11 @@ static TCGv gen_lea_indexed(CPUM68KState *env, 
DisasContext *s, TCGv base)
 add = tmp;
 }
 } else {
-add = mark_to_release(s, tcg_const_i32(bd));
+add = tcg_const_i32(bd);
 }
 if ((ext & 3) != 0) {
 /* memory indirect */
-base = mark_to_release(s, gen_load(s, OS_LONG, add, 0, 
IS_USER(s)));
+base = gen_load(s, OS_LONG, add, 0, IS_USER(s));
 if ((ext & 0x44) == 4) {
 add = gen_addr_index(s, ext, tmp);
 tcg_gen_add_i32(tmp, add, base);
@@ -546,7 +519,7 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext 
*s, TCGv base)
 }
 } else {
 /* brief extension word format */
-tmp = mark_to_release(s, tcg_temp_new());
+tmp = tcg_temp_new();
 add = gen_addr_index(s, ext, tmp);
 if (!IS_NULL_QREG(base)) {
 tcg_gen_add_i32(tmp, add, base);
@@ -676,7 +649,7 @@ static inline TCGv gen_extend(DisasContext *s, TCGv val, 
int opsize, int sign)
 if (opsize == OS_LONG) {
 tmp = val;
 } else {
-tmp = mark_to_release(s, tcg_temp_new());
+tmp = tcg_temp_new();
 gen_ext(tmp, val, opsize, sign);
 }
 
@@ -802,7 +775,7 @@ static TCGv gen_lea_mode(CPUM68KState *env, DisasContext *s,
 return NULL_QREG;
 }
 reg = get_areg(s, reg0);
-tmp = mark_to_release(s, tcg_temp_new());
+tmp = tcg_temp_new();
 if (reg0 == 7 && opsize == OS_BYTE &&
 m68k_feature(s->env, M68K_FEATURE_M68K)) {
 tcg_gen_subi_i32(tmp, reg, 2);
@@ -812,7 +785,7 @@ static TCGv gen_lea_mode(CPUM68KState *env, DisasContext *s,
 return tmp;
 case 5: /* Indirect displacement.  */
 reg = get_areg(s, reg0);
-tmp = mark_to_release(s, tcg_temp_new());
+tmp = tcg_temp_new();
 ext = read_im16(env, s);
 tcg_gen_addi_i32(tmp, reg, (int16_t)ext);
 return tmp;
@@ -823,14 +796,14 @@ static TCGv gen_lea_mode(CPUM68KState *env, DisasContext 
*s,
 switch (reg0) {
 case 0: /* Absolute short.  */
 offset = (int16_t)read_im16(env, s);
-return mark_to_release(s, tcg_const_i32(offset));
+return tcg_const_i32(offset);
 case 1: /* Absolute long.  */
 offset = read_im32(env, s);
-return mark_to_release(s, tcg_const_i32(offset));
+return tcg_const_i32(offset);
 case 2: /* pc 

[PATCH v2 07/76] target/arm: Drop DisasContext.tmp_a64

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries,
therefore there's no need to record temps for later freeing.

Signed-off-by: Richard Henderson 
---
 target/arm/translate.h |  3 ---
 target/arm/translate-a64.c | 25 +
 2 files changed, 1 insertion(+), 27 deletions(-)

diff --git a/target/arm/translate.h b/target/arm/translate.h
index db29e8d799..d7fdbc1e3e 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -149,9 +149,6 @@ typedef struct DisasContext {
 int c15_cpar;
 /* TCG op of the current insn_start.  */
 TCGOp *insn_start;
-#define TMP_A64_MAX 16
-int tmp_a64_count;
-TCGv_i64 tmp_a64[TMP_A64_MAX];
 } DisasContext;
 
 typedef struct DisasCompare {
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 2a0bba3815..98d1bee5d5 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -408,27 +408,9 @@ static void gen_goto_tb(DisasContext *s, int n, int64_t 
diff)
 }
 }
 
-static void init_tmp_a64_array(DisasContext *s)
-{
-#ifdef CONFIG_DEBUG_TCG
-memset(s->tmp_a64, 0, sizeof(s->tmp_a64));
-#endif
-s->tmp_a64_count = 0;
-}
-
-static void free_tmp_a64(DisasContext *s)
-{
-int i;
-for (i = 0; i < s->tmp_a64_count; i++) {
-tcg_temp_free_i64(s->tmp_a64[i]);
-}
-init_tmp_a64_array(s);
-}
-
 TCGv_i64 new_tmp_a64(DisasContext *s)
 {
-assert(s->tmp_a64_count < TMP_A64_MAX);
-return s->tmp_a64[s->tmp_a64_count++] = tcg_temp_new_i64();
+return tcg_temp_new_i64();
 }
 
 TCGv_i64 new_tmp_a64_zero(DisasContext *s)
@@ -14781,8 +14763,6 @@ static void 
aarch64_tr_init_disas_context(DisasContextBase *dcbase,
 bound = 1;
 }
 dc->base.max_insns = MIN(dc->base.max_insns, bound);
-
-init_tmp_a64_array(dc);
 }
 
 static void aarch64_tr_tb_start(DisasContextBase *db, CPUState *cpu)
@@ -14938,9 +14918,6 @@ static void aarch64_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
 break;
 }
 
-/* if we allocated any temporaries, free them here */
-free_tmp_a64(s);
-
 /*
  * After execution of most insns, btype is reset to 0.
  * Note that we set btype == -1 when the insn sets btype.
-- 
2.34.1




[PATCH v2 09/76] target/arm: Drop new_tmp_a64_zero

2023-02-26 Thread Richard Henderson
Only the use within cpu_reg requires a writable temp,
so inline new_tmp_a64_zero there.  All other uses are
fine with a constant temp, so use tcg_constant_i64(0).

Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.h |  1 -
 target/arm/translate-a64.c | 41 +-
 2 files changed, 18 insertions(+), 24 deletions(-)

diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
index 8ac126991f..0576c4ea12 100644
--- a/target/arm/translate-a64.h
+++ b/target/arm/translate-a64.h
@@ -18,7 +18,6 @@
 #ifndef TARGET_ARM_TRANSLATE_A64_H
 #define TARGET_ARM_TRANSLATE_A64_H
 
-TCGv_i64 new_tmp_a64_zero(DisasContext *s);
 TCGv_i64 cpu_reg(DisasContext *s, int reg);
 TCGv_i64 cpu_reg_sp(DisasContext *s, int reg);
 TCGv_i64 read_cpu_reg(DisasContext *s, int reg, int sf);
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 04872d9925..b5d6508cbc 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -408,13 +408,6 @@ static void gen_goto_tb(DisasContext *s, int n, int64_t 
diff)
 }
 }
 
-TCGv_i64 new_tmp_a64_zero(DisasContext *s)
-{
-TCGv_i64 t = tcg_temp_new_i64();
-tcg_gen_movi_i64(t, 0);
-return t;
-}
-
 /*
  * Register access functions
  *
@@ -433,7 +426,9 @@ TCGv_i64 new_tmp_a64_zero(DisasContext *s)
 TCGv_i64 cpu_reg(DisasContext *s, int reg)
 {
 if (reg == 31) {
-return new_tmp_a64_zero(s);
+TCGv_i64 t = tcg_temp_new_i64();
+tcg_gen_movi_i64(t, 0);
+return t;
 } else {
 return cpu_X[reg];
 }
@@ -1532,7 +1527,7 @@ static void handle_hint(DisasContext *s, uint32_t insn,
 case 0b11000: /* PACIAZ */
 if (s->pauth_active) {
 gen_helper_pacia(cpu_X[30], cpu_env, cpu_X[30],
-new_tmp_a64_zero(s));
+ tcg_constant_i64(0));
 }
 break;
 case 0b11001: /* PACIASP */
@@ -1543,7 +1538,7 @@ static void handle_hint(DisasContext *s, uint32_t insn,
 case 0b11010: /* PACIBZ */
 if (s->pauth_active) {
 gen_helper_pacib(cpu_X[30], cpu_env, cpu_X[30],
-new_tmp_a64_zero(s));
+ tcg_constant_i64(0));
 }
 break;
 case 0b11011: /* PACIBSP */
@@ -1554,7 +1549,7 @@ static void handle_hint(DisasContext *s, uint32_t insn,
 case 0b11100: /* AUTIAZ */
 if (s->pauth_active) {
 gen_helper_autia(cpu_X[30], cpu_env, cpu_X[30],
-  new_tmp_a64_zero(s));
+ tcg_constant_i64(0));
 }
 break;
 case 0b11101: /* AUTIASP */
@@ -1565,7 +1560,7 @@ static void handle_hint(DisasContext *s, uint32_t insn,
 case 0b0: /* AUTIBZ */
 if (s->pauth_active) {
 gen_helper_autib(cpu_X[30], cpu_env, cpu_X[30],
-  new_tmp_a64_zero(s));
+ tcg_constant_i64(0));
 }
 break;
 case 0b1: /* AUTIBSP */
@@ -2285,7 +2280,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t 
insn)
 if (op4 != 0x1f) {
 goto do_unallocated;
 }
-modifier = new_tmp_a64_zero(s);
+modifier = tcg_constant_i64(0);
 }
 if (s->pauth_active) {
 dst = tcg_temp_new_i64();
@@ -3550,10 +3545,10 @@ static void disas_ldst_pac(DisasContext *s, uint32_t 
insn,
 if (s->pauth_active) {
 if (use_key_a) {
 gen_helper_autda(dirty_addr, cpu_env, dirty_addr,
- new_tmp_a64_zero(s));
+ tcg_constant_i64(0));
 } else {
 gen_helper_autdb(dirty_addr, cpu_env, dirty_addr,
- new_tmp_a64_zero(s));
+ tcg_constant_i64(0));
 }
 }
 
@@ -5628,7 +5623,7 @@ static void disas_data_proc_1src(DisasContext *s, 
uint32_t insn)
 goto do_unallocated;
 } else if (s->pauth_active) {
 tcg_rd = cpu_reg(s, rd);
-gen_helper_pacia(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
+gen_helper_pacia(tcg_rd, cpu_env, tcg_rd, tcg_constant_i64(0));
 }
 break;
 case MAP(1, 0x01, 0x09): /* PACIZB */
@@ -5636,7 +5631,7 @@ static void disas_data_proc_1src(DisasContext *s, 
uint32_t insn)
 goto do_unallocated;
 } else if (s->pauth_active) {
 tcg_rd = cpu_reg(s, rd);
-gen_helper_pacib(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
+gen_helper_pacib(tcg_rd, cpu_env, tcg_rd, tcg_constant_i64(0));
 }
 break;
 case MAP(1, 0x01, 0x0a): /* PACDZA */
@@ -5644,7 +5639,7 @@ static void disas_data_proc_1src(DisasContext *s, 
uint32_t insn)
 goto do_unallocated;
 } else if (s->pauth_active) {
 tcg_rd = cpu_reg(s, rd);
-gen_help

[PATCH v2 32/76] target/loongarch: Drop tcg_temp_free

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries.

Reviewed-by: Song Gao 
Signed-off-by: Richard Henderson 
---
 target/loongarch/insn_trans/trans_arith.c.inc | 12 ---
 .../loongarch/insn_trans/trans_atomic.c.inc   |  3 --
 target/loongarch/insn_trans/trans_bit.c.inc   | 12 ---
 target/loongarch/insn_trans/trans_fcmp.c.inc  |  3 --
 .../loongarch/insn_trans/trans_fmemory.c.inc  | 20 ++-
 target/loongarch/insn_trans/trans_fmov.c.inc  |  6 
 .../loongarch/insn_trans/trans_memory.c.inc   | 34 +++
 .../insn_trans/trans_privileged.c.inc |  4 ---
 target/loongarch/insn_trans/trans_shift.c.inc | 11 --
 9 files changed, 6 insertions(+), 99 deletions(-)

diff --git a/target/loongarch/insn_trans/trans_arith.c.inc 
b/target/loongarch/insn_trans/trans_arith.c.inc
index 8e45eadbc8..43d6cf261d 100644
--- a/target/loongarch/insn_trans/trans_arith.c.inc
+++ b/target/loongarch/insn_trans/trans_arith.c.inc
@@ -100,14 +100,12 @@ static void gen_mulh_d(TCGv dest, TCGv src1, TCGv src2)
 {
 TCGv discard = tcg_temp_new();
 tcg_gen_muls2_tl(discard, dest, src1, src2);
-tcg_temp_free(discard);
 }
 
 static void gen_mulh_du(TCGv dest, TCGv src1, TCGv src2)
 {
 TCGv discard = tcg_temp_new();
 tcg_gen_mulu2_tl(discard, dest, src1, src2);
-tcg_temp_free(discard);
 }
 
 static void prep_divisor_d(TCGv ret, TCGv src1, TCGv src2)
@@ -129,9 +127,6 @@ static void prep_divisor_d(TCGv ret, TCGv src1, TCGv src2)
 tcg_gen_and_tl(ret, ret, t0);
 tcg_gen_or_tl(ret, ret, t1);
 tcg_gen_movcond_tl(TCG_COND_NE, ret, ret, zero, ret, src2);
-
-tcg_temp_free(t0);
-tcg_temp_free(t1);
 }
 
 static void prep_divisor_du(TCGv ret, TCGv src2)
@@ -152,7 +147,6 @@ static void gen_div_d(TCGv dest, TCGv src1, TCGv src2)
 TCGv t0 = tcg_temp_new();
 prep_divisor_d(t0, src1, src2);
 tcg_gen_div_tl(dest, src1, t0);
-tcg_temp_free(t0);
 }
 
 static void gen_rem_d(TCGv dest, TCGv src1, TCGv src2)
@@ -160,7 +154,6 @@ static void gen_rem_d(TCGv dest, TCGv src1, TCGv src2)
 TCGv t0 = tcg_temp_new();
 prep_divisor_d(t0, src1, src2);
 tcg_gen_rem_tl(dest, src1, t0);
-tcg_temp_free(t0);
 }
 
 static void gen_div_du(TCGv dest, TCGv src1, TCGv src2)
@@ -168,7 +161,6 @@ static void gen_div_du(TCGv dest, TCGv src1, TCGv src2)
 TCGv t0 = tcg_temp_new();
 prep_divisor_du(t0, src2);
 tcg_gen_divu_tl(dest, src1, t0);
-tcg_temp_free(t0);
 }
 
 static void gen_rem_du(TCGv dest, TCGv src1, TCGv src2)
@@ -176,7 +168,6 @@ static void gen_rem_du(TCGv dest, TCGv src1, TCGv src2)
 TCGv t0 = tcg_temp_new();
 prep_divisor_du(t0, src2);
 tcg_gen_remu_tl(dest, src1, t0);
-tcg_temp_free(t0);
 }
 
 static void gen_div_w(TCGv dest, TCGv src1, TCGv src2)
@@ -185,7 +176,6 @@ static void gen_div_w(TCGv dest, TCGv src1, TCGv src2)
 /* We need not check for integer overflow for div_w. */
 prep_divisor_du(t0, src2);
 tcg_gen_div_tl(dest, src1, t0);
-tcg_temp_free(t0);
 }
 
 static void gen_rem_w(TCGv dest, TCGv src1, TCGv src2)
@@ -194,7 +184,6 @@ static void gen_rem_w(TCGv dest, TCGv src1, TCGv src2)
 /* We need not check for integer overflow for rem_w. */
 prep_divisor_du(t0, src2);
 tcg_gen_rem_tl(dest, src1, t0);
-tcg_temp_free(t0);
 }
 
 static void gen_alsl(TCGv dest, TCGv src1, TCGv src2, target_long sa)
@@ -202,7 +191,6 @@ static void gen_alsl(TCGv dest, TCGv src1, TCGv src2, 
target_long sa)
 TCGv t0 = tcg_temp_new();
 tcg_gen_shli_tl(t0, src1, sa);
 tcg_gen_add_tl(dest, t0, src2);
-tcg_temp_free(t0);
 }
 
 static bool trans_lu32i_d(DisasContext *ctx, arg_lu32i_d *a)
diff --git a/target/loongarch/insn_trans/trans_atomic.c.inc 
b/target/loongarch/insn_trans/trans_atomic.c.inc
index 6763c1c301..612709f2a7 100644
--- a/target/loongarch/insn_trans/trans_atomic.c.inc
+++ b/target/loongarch/insn_trans/trans_atomic.c.inc
@@ -14,7 +14,6 @@ static bool gen_ll(DisasContext *ctx, arg_rr_i *a, MemOp mop)
 tcg_gen_st_tl(t0, cpu_env, offsetof(CPULoongArchState, lladdr));
 tcg_gen_st_tl(dest, cpu_env, offsetof(CPULoongArchState, llval));
 gen_set_gpr(a->rd, dest, EXT_NONE);
-tcg_temp_free(t0);
 
 return true;
 }
@@ -43,8 +42,6 @@ static bool gen_sc(DisasContext *ctx, arg_rr_i *a, MemOp mop)
 tcg_gen_setcond_tl(TCG_COND_EQ, dest, t0, cpu_llval);
 gen_set_label(done);
 gen_set_gpr(a->rd, dest, EXT_NONE);
-tcg_temp_free(t0);
-tcg_temp_free(val);
 
 return true;
 }
diff --git a/target/loongarch/insn_trans/trans_bit.c.inc 
b/target/loongarch/insn_trans/trans_bit.c.inc
index b01e4aeb23..25b4d7858b 100644
--- a/target/loongarch/insn_trans/trans_bit.c.inc
+++ b/target/loongarch/insn_trans/trans_bit.c.inc
@@ -122,9 +122,6 @@ static void gen_revb_2h(TCGv dest, TCGv src1)
 tcg_gen_and_tl(t1, src1, mask);
 tcg_gen_shli_tl(t1, t1, 8);
 tcg_gen_or_tl(dest, t0, t1);
-
-tcg_temp_free(t0);
-tcg_temp_free(t1);
 }
 
 static void gen_revb_4h(TCGv dest, TC

[PATCH v2 24/76] target/cris: Drop tcg_temp_free

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries.

Signed-off-by: Richard Henderson 
---
 target/cris/translate.c | 70 -
 target/cris/translate_v10.c.inc | 41 ---
 2 files changed, 111 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index 439af701e6..5172c9b9b2 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -178,7 +178,6 @@ static const int preg_sizes[] = {
 do { \
 TCGv tc = tcg_const_tl(c); \
 t_gen_mov_env_TN(member, tc); \
-tcg_temp_free(tc); \
 } while (0)
 
 static inline void t_gen_mov_TN_preg(TCGv tn, int r)
@@ -271,7 +270,6 @@ static inline void t_gen_raise_exception(uint32_t index)
 {
 TCGv_i32 tmp = tcg_const_i32(index);
 gen_helper_raise_exception(cpu_env, tmp);
-tcg_temp_free_i32(tmp);
 }
 
 static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
@@ -286,8 +284,6 @@ static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
 tcg_gen_sar_tl(t0, t0, t_31);
 tcg_gen_and_tl(t0, t0, d);
 tcg_gen_xor_tl(d, d, t0);
-tcg_temp_free(t0);
-tcg_temp_free(t_31);
 }
 
 static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
@@ -303,8 +299,6 @@ static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
 tcg_gen_sar_tl(t0, t0, t_31);
 tcg_gen_and_tl(t0, t0, d);
 tcg_gen_xor_tl(d, d, t0);
-tcg_temp_free(t0);
-tcg_temp_free(t_31);
 }
 
 static void t_gen_asr(TCGv d, TCGv a, TCGv b)
@@ -319,8 +313,6 @@ static void t_gen_asr(TCGv d, TCGv a, TCGv b)
 tcg_gen_sub_tl(t0, t_31, b);
 tcg_gen_sar_tl(t0, t0, t_31);
 tcg_gen_or_tl(d, d, t0);
-tcg_temp_free(t0);
-tcg_temp_free(t_31);
 }
 
 static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
@@ -335,7 +327,6 @@ static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
 tcg_gen_shli_tl(d, a, 1);
 tcg_gen_sub_tl(t, d, b);
 tcg_gen_movcond_tl(TCG_COND_GEU, d, d, b, t, d);
-tcg_temp_free(t);
 }
 
 static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs)
@@ -353,7 +344,6 @@ static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv 
ccs)
 tcg_gen_sari_tl(t, t, 31);
 tcg_gen_and_tl(t, t, b);
 tcg_gen_add_tl(d, d, t);
-tcg_temp_free(t);
 }
 
 /* Extended arithmetics on CRIS.  */
@@ -369,7 +359,6 @@ static inline void t_gen_add_flag(TCGv d, int flag)
 tcg_gen_shri_tl(c, c, flag);
 }
 tcg_gen_add_tl(d, d, c);
-tcg_temp_free(c);
 }
 
 static inline void t_gen_addx_carry(DisasContext *dc, TCGv d)
@@ -381,7 +370,6 @@ static inline void t_gen_addx_carry(DisasContext *dc, TCGv 
d)
 /* C flag is already at bit 0.  */
 tcg_gen_andi_tl(c, c, C_FLAG);
 tcg_gen_add_tl(d, d, c);
-tcg_temp_free(c);
 }
 }
 
@@ -394,7 +382,6 @@ static inline void t_gen_subx_carry(DisasContext *dc, TCGv 
d)
 /* C flag is already at bit 0.  */
 tcg_gen_andi_tl(c, c, C_FLAG);
 tcg_gen_sub_tl(d, d, c);
-tcg_temp_free(c);
 }
 }
 
@@ -414,8 +401,6 @@ static inline void t_gen_swapb(TCGv d, TCGv s)
 tcg_gen_shri_tl(t, org_s, 8);
 tcg_gen_andi_tl(t, t, 0x00ff00ff);
 tcg_gen_or_tl(d, d, t);
-tcg_temp_free(t);
-tcg_temp_free(org_s);
 }
 
 /* Swap the halfwords of the s operand.  */
@@ -428,7 +413,6 @@ static inline void t_gen_swapw(TCGv d, TCGv s)
 tcg_gen_shli_tl(d, t, 16);
 tcg_gen_shri_tl(t, t, 16);
 tcg_gen_or_tl(d, d, t);
-tcg_temp_free(t);
 }
 
 /* Reverse the within each byte.
@@ -475,8 +459,6 @@ static void t_gen_swapr(TCGv d, TCGv s)
 tcg_gen_andi_tl(t, t,  bitrev[i].mask);
 tcg_gen_or_tl(d, d, t);
 }
-tcg_temp_free(t);
-tcg_temp_free(org_s);
 }
 
 static bool use_goto_tb(DisasContext *dc, target_ulong dest)
@@ -778,9 +760,6 @@ static void cris_alu(DisasContext *dc, int op,
 }
 tcg_gen_or_tl(d, d, tmp);
 }
-if (tmp != d) {
-tcg_temp_free(tmp);
-}
 }
 
 static int arith_cc(DisasContext *dc)
@@ -919,8 +898,6 @@ static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
 tcg_gen_shli_tl(cc, tmp, 2);
 tcg_gen_and_tl(cc, tmp, cc);
 tcg_gen_andi_tl(cc, cc, Z_FLAG);
-
-tcg_temp_free(tmp);
 }
 break;
 case CC_GE:
@@ -959,9 +936,6 @@ static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
 tcg_gen_xori_tl(n, n, 2);
 tcg_gen_and_tl(cc, z, n);
 tcg_gen_andi_tl(cc, cc, 2);
-
-tcg_temp_free(n);
-tcg_temp_free(z);
 }
 break;
 case CC_LE:
@@ -980,9 +954,6 @@ static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
 tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
 tcg_gen_or_tl(cc, z, n);
 tcg_gen_andi_tl(cc, cc, 2);
-
-tcg_temp_free(n);
-tcg_temp_free(z);
 }
 break;
 case CC_P:
@@ -1282,7 +1253,6 @@ static int dec_addq(CPUCRISState *env, DisasContext *dc)
 c = tcg_const_tl(dc->op1);
 cris_al

[PATCH v2 35/76] target/m68k: Drop tcg_temp_free

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries.

Signed-off-by: Richard Henderson 
---
 target/m68k/translate.c | 181 
 1 file changed, 181 deletions(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index d7237b6a99..3055d2d246 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -138,7 +138,6 @@ static void delay_set_areg(DisasContext *s, unsigned regno,
 {
 if (s->writeback_mask & (1 << regno)) {
 if (give_temp) {
-tcg_temp_free(s->writeback[regno]);
 s->writeback[regno] = val;
 } else {
 tcg_gen_mov_i32(s->writeback[regno], val);
@@ -163,7 +162,6 @@ static void do_writebacks(DisasContext *s)
 do {
 unsigned regno = ctz32(mask);
 tcg_gen_mov_i32(cpu_aregs[regno], s->writeback[regno]);
-tcg_temp_free(s->writeback[regno]);
 mask &= mask - 1;
 } while (mask);
 }
@@ -270,7 +268,6 @@ static void gen_raise_exception(int nr)
 
 tmp = tcg_const_i32(nr);
 gen_helper_raise_exception(cpu_env, tmp);
-tcg_temp_free_i32(tmp);
 }
 
 static void gen_raise_exception_format2(DisasContext *s, int nr,
@@ -582,9 +579,7 @@ static void gen_flush_flags(DisasContext *s)
 gen_ext(t0, t0, s->cc_op - CC_OP_ADDB, 1);
 tcg_gen_xor_i32(t1, QREG_CC_N, QREG_CC_V);
 tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0);
-tcg_temp_free(t0);
 tcg_gen_andc_i32(QREG_CC_V, t1, QREG_CC_V);
-tcg_temp_free(t1);
 break;
 
 case CC_OP_SUBB:
@@ -599,9 +594,7 @@ static void gen_flush_flags(DisasContext *s)
 gen_ext(t0, t0, s->cc_op - CC_OP_SUBB, 1);
 tcg_gen_xor_i32(t1, QREG_CC_N, t0);
 tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0);
-tcg_temp_free(t0);
 tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, t1);
-tcg_temp_free(t1);
 break;
 
 case CC_OP_CMPB:
@@ -615,7 +608,6 @@ static void gen_flush_flags(DisasContext *s)
 tcg_gen_xor_i32(t0, QREG_CC_Z, QREG_CC_N);
 tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, QREG_CC_N);
 tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, t0);
-tcg_temp_free(t0);
 tcg_gen_mov_i32(QREG_CC_N, QREG_CC_Z);
 break;
 
@@ -633,7 +625,6 @@ static void gen_flush_flags(DisasContext *s)
 default:
 t0 = tcg_const_i32(s->cc_op);
 gen_helper_flush_flags(cpu_env, t0);
-tcg_temp_free(t0);
 s->cc_op_synced = 1;
 break;
 }
@@ -729,14 +720,12 @@ static void gen_partset_reg(int opsize, TCGv reg, TCGv 
val)
 tmp = tcg_temp_new();
 tcg_gen_ext8u_i32(tmp, val);
 tcg_gen_or_i32(reg, reg, tmp);
-tcg_temp_free(tmp);
 break;
 case OS_WORD:
 tcg_gen_andi_i32(reg, reg, 0x);
 tmp = tcg_temp_new();
 tcg_gen_ext16u_i32(tmp, val);
 tcg_gen_or_i32(reg, reg, tmp);
-tcg_temp_free(tmp);
 break;
 case OS_LONG:
 case OS_SINGLE:
@@ -970,12 +959,10 @@ static void gen_fp_move(TCGv_ptr dest, TCGv_ptr src)
 t32 = tcg_temp_new();
 tcg_gen_ld16u_i32(t32, src, offsetof(FPReg, l.upper));
 tcg_gen_st16_i32(t32, dest, offsetof(FPReg, l.upper));
-tcg_temp_free(t32);
 
 t64 = tcg_temp_new_i64();
 tcg_gen_ld_i64(t64, src, offsetof(FPReg, l.lower));
 tcg_gen_st_i64(t64, dest, offsetof(FPReg, l.lower));
-tcg_temp_free_i64(t64);
 }
 
 static void gen_load_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp,
@@ -1029,8 +1016,6 @@ static void gen_load_fp(DisasContext *s, int opsize, TCGv 
addr, TCGv_ptr fp,
 default:
 g_assert_not_reached();
 }
-tcg_temp_free(tmp);
-tcg_temp_free_i64(t64);
 }
 
 static void gen_store_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp,
@@ -1084,8 +1069,6 @@ static void gen_store_fp(DisasContext *s, int opsize, 
TCGv addr, TCGv_ptr fp,
 default:
 g_assert_not_reached();
 }
-tcg_temp_free(tmp);
-tcg_temp_free_i64(t64);
 }
 
 static void gen_ldst_fp(DisasContext *s, int opsize, TCGv addr,
@@ -1141,7 +1124,6 @@ static int gen_ea_mode_fp(CPUM68KState *env, DisasContext 
*s, int mode,
 default:
 g_assert_not_reached();
 }
-tcg_temp_free(tmp);
 }
 return 0;
 case 1: /* Address register direct.  */
@@ -1187,27 +1169,22 @@ static int gen_ea_mode_fp(CPUM68KState *env, 
DisasContext *s, int mode,
 case OS_BYTE:
 tmp = tcg_const_i32((int8_t)read_im8(env, s));
 gen_helper_exts32(cpu_env, fp, tmp);
-tcg_temp_free(tmp);
 break;
 case OS_WORD:
 tmp = tcg_const_i32((int16_t)read_im16(env, s));
 gen_helper_exts32(cpu_env, fp, tmp);
-tcg_temp_free(tmp);
 break;
 case OS_LONG:
 tmp = tcg_const_i32(read_im32(env, s));
 gen_hel

[PATCH v2 04/76] target/arm: Remove arm_free_cc, a64_free_cc

2023-02-26 Thread Richard Henderson
Translators are no longer required to free tcg temporaries.

Signed-off-by: Richard Henderson 
---
 target/arm/translate.h |  1 -
 target/arm/translate-a64.c | 17 -
 target/arm/translate.c |  9 -
 3 files changed, 4 insertions(+), 23 deletions(-)

diff --git a/target/arm/translate.h b/target/arm/translate.h
index 3717824b75..7f52f08c5e 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -304,7 +304,6 @@ static inline void gen_a64_update_pc(DisasContext *s, 
target_long diff)
 #endif
 
 void arm_test_cc(DisasCompare *cmp, int cc);
-void arm_free_cc(DisasCompare *cmp);
 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
 void arm_gen_test_cc(int cc, TCGLabel *label);
 MemOp pow2_align(unsigned i);
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 98537bc2ef..2a0bba3815 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -319,18 +319,13 @@ static void a64_test_cc(DisasCompare64 *c64, int cc)
 
 arm_test_cc(&c32, cc);
 
-/* Sign-extend the 32-bit value so that the GE/LT comparisons work
-   * properly.  The NE/EQ comparisons are also fine with this choice.  */
+/*
+ * Sign-extend the 32-bit value so that the GE/LT comparisons work
+ * properly.  The NE/EQ comparisons are also fine with this choice.
+  */
 c64->cond = c32.cond;
 c64->value = tcg_temp_new_i64();
 tcg_gen_ext_i32_i64(c64->value, c32.value);
-
-arm_free_cc(&c32);
-}
-
-static void a64_free_cc(DisasCompare64 *c64)
-{
-tcg_temp_free_i64(c64->value);
 }
 
 static void gen_rebuild_hflags(DisasContext *s)
@@ -5315,7 +5310,6 @@ static void disas_cc(DisasContext *s, uint32_t insn)
 tcg_t0 = tcg_temp_new_i32();
 arm_test_cc(&c, cond);
 tcg_gen_setcondi_i32(tcg_invert_cond(c.cond), tcg_t0, c.value, 0);
-arm_free_cc(&c);
 
 /* Load the arguments for the new comparison.  */
 if (is_imm) {
@@ -5435,8 +5429,6 @@ static void disas_cond_select(DisasContext *s, uint32_t 
insn)
 tcg_gen_movcond_i64(c.cond, tcg_rd, c.value, zero, t_true, t_false);
 }
 
-a64_free_cc(&c);
-
 if (!sf) {
 tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
 }
@@ -6256,7 +6248,6 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
 tcg_gen_movcond_i64(c.cond, t_true, c.value, tcg_constant_i64(0),
 t_true, t_false);
 tcg_temp_free_i64(t_false);
-a64_free_cc(&c);
 
 /* Note that sregs & hregs write back zeros to the high bits,
and we've already done the zero-extension.  */
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 614c438786..a0a298f8f7 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -754,13 +754,6 @@ void arm_test_cc(DisasCompare *cmp, int cc)
 cmp->value_global = global;
 }
 
-void arm_free_cc(DisasCompare *cmp)
-{
-if (!cmp->value_global) {
-tcg_temp_free_i32(cmp->value);
-}
-}
-
 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
 {
 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
@@ -771,7 +764,6 @@ void arm_gen_test_cc(int cc, TCGLabel *label)
 DisasCompare cmp;
 arm_test_cc(&cmp, cc);
 arm_jump_cc(&cmp, label);
-arm_free_cc(&cmp);
 }
 
 void gen_set_condexec(DisasContext *s)
@@ -9125,7 +9117,6 @@ static bool trans_CSEL(DisasContext *s, arg_CSEL *a)
 
 arm_test_cc(&c, a->fcond);
 tcg_gen_movcond_i32(c.cond, rn, c.value, zero, rn, rm);
-arm_free_cc(&c);
 
 store_reg(s, a->rd, rn);
 tcg_temp_free_i32(rm);
-- 
2.34.1




  1   2   >