RE: [PATCH] contrib/plugins/execlog: Fix compiler warning

2024-03-24 Thread Xingtao Yao (Fujitsu)
Hi Pierrick,

thanks for your reply,  and I will modify and push the patch later.

thanks
Xingtao

> -Original Message-
> From: Pierrick Bouvier 
> Sent: Monday, March 25, 2024 12:31 PM
> To: Yao, Xingtao/姚 幸涛 ; Peter Maydell
> 
> Cc: alex.ben...@linaro.org; erdn...@crans.org; ma.mando...@gmail.com;
> qemu-devel@nongnu.org
> Subject: Re: [PATCH] contrib/plugins/execlog: Fix compiler warning
> 
> On 3/25/24 07:00, Xingtao Yao (Fujitsu) wrote:
> > Pete:
> > Thanks for your comment.
> >
> > I also find a similar patch written by Pierrick:
> > https://lore.kernel.org/qemu-devel/20240118032400.3762658-15-pierrick.
> > bouv...@linaro.org/ but for some reason, the patch was not merged yet.
> >
> > shall I need to continue tracking the fixes of this bug?
> >
> 
> Hi Xingtao,
> 
> you're doing the right thing here. In my original patch, there was no
> consideration for backward compatibility, to the opposite of what you did.
> 
> Alex will be out for several weeks, so it might take some time to get this 
> merged,
> but I'm definitely voting for this .
> 
> Pierrick
> 
> >> -Original Message-
> >> From: Peter Maydell 
> >> Sent: Friday, March 22, 2024 7:50 PM
> >> To: Yao, Xingtao/姚 幸涛 
> >> Cc: alex.ben...@linaro.org; erdn...@crans.org; ma.mando...@gmail.com;
> >> pierrick.bouv...@linaro.org; qemu-devel@nongnu.org
> >> Subject: Re: [PATCH] contrib/plugins/execlog: Fix compiler warning
> >>
> >> On Wed, 20 Mar 2024 at 02:05, Yao Xingtao via 
> >> wrote:
> >>>
> >>> 1. The g_pattern_match_string() is deprecated when glib2 version >=
> 2.70.
> >>> Use g_pattern_spec_match_string() instead to avoid this problem.
> >>>
> >>> 2. The type of second parameter in g_ptr_array_add() is
> >>> 'gpointer' {aka 'void *'}, but the type of reg->name is 'const char*'.
> >>> Cast the type of reg->name to 'gpointer' to avoid this problem.
> >>>
> >>> compiler warning message:
> >>> /root/qemu/contrib/plugins/execlog.c:330:17: warning:
> >> ‘g_pattern_match_string’
> >>> is deprecated: Use 'g_pattern_spec_match_string'
> >>> instead [-Wdeprecated-declarations]
> >>>330 | if (g_pattern_match_string(pat, rd->name) ||
> >>>| ^~
> >>> In file included from /usr/include/glib-2.0/glib.h:67,
> >>>   from /root/qemu/contrib/plugins/execlog.c:9:
> >>> /usr/include/glib-2.0/glib/gpattern.h:57:15: note: declared here
> >>> 57 | gboolean  g_pattern_match_string   (GPatternSpec
> *pspec,
> >>>|   ^~
> >>> /root/qemu/contrib/plugins/execlog.c:331:21: warning:
> >> ‘g_pattern_match_string’
> >>> is deprecated: Use 'g_pattern_spec_match_string'
> >>> instead [-Wdeprecated-declarations]
> >>>331 | g_pattern_match_string(pat, rd_lower)) {
> >>>| ^~
> >>> /usr/include/glib-2.0/glib/gpattern.h:57:15: note: declared here
> >>> 57 | gboolean  g_pattern_match_string   (GPatternSpec
> *pspec,
> >>>|   ^~
> >>> /root/qemu/contrib/plugins/execlog.c:339:63: warning: passing
> >>> argument
> >>> 2 of ‘g_ptr_array_add’ discards ‘const’ qualifier from pointer
> >>> target type [-Wdiscarded-qualifiers]
> >>>339 | g_ptr_array_add(all_reg_names,
> >> reg->name);
> >>>|
> >> ~~~^~
> >>> In file included from /usr/include/glib-2.0/glib.h:33:
> >>> /usr/include/glib-2.0/glib/garray.h:198:62: note: expected ‘gpointer’
> >>> {aka ‘void *’} but argument is of type ‘const char *’
> >>>198 |gpointer
> >> data);
> >>>|
> >> ~~^~~~
> >>>
> >>
> >> Hi; thanks for this patch.
> >>
> >> This fixes a bug reported in the bug tracker so we should put
> >>
> >> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2210
> >>
> >> in the commit message just above your signed-off-by tag.
> >>
> >>
> >>> Signed-off-by: Yao Xingtao 
> > I will if needed.
> >
> >>> ---
> >>>   contrib/plugins/execlog.c | 7 ++-
> >>>   1 file changed, 6 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
> >>> index a1dfd59ab7..41f6774116 100644
> >>> --- a/contrib/plugins/execlog.c
> >>> +++ b/contrib/plugins/execlog.c
> >>> @@ -327,8 +327,13 @@ static GPtrArray *registers_init(int vcpu_index)
> >>>   for (int p = 0; p < rmatches->len; p++) {
> >>>   g_autoptr(GPatternSpec) pat =
> >> g_pattern_spec_new(rmatches->pdata[p]);
> >>>   g_autofree gchar *rd_lower =
> >>> g_utf8_strdown(rd->name, -1);
> >>> +#if GLIB_VERSION_MAX_ALLOWED < G_ENCODE_VERSION(2, 70)
> >>
> >> Elsewhere we do glib version checks with
> >>
> >> #if GLIB_CHECK_VERSION(2, 70, 0)
> >>  code for 2.70.0 and up;
> >> #else
> >>  code for older versions
> >> #endif
> >>
> >> so I think we should probably do that here too.
> >>
> >>>   if 

Re: [PATCH 04/12] qapi: Tidy up indentation of add_client's example

2024-03-24 Thread Markus Armbruster
Markus Armbruster  writes:

> Commit d23055b8db8 (qapi: Require descriptions and tagged sections to
> be indented) indented add_client's example too much.  Revert that.
>
> Signed-off-by: Markus Armbruster 
> ---
>  qapi/misc.json | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/qapi/misc.json b/qapi/misc.json
> index 1b0c5dad88..ec30e5c570 100644
> --- a/qapi/misc.json
> +++ b/qapi/misc.json
> @@ -32,9 +32,9 @@
>  #
>  # Example:
>  #
> -# -> { "execute": "add_client", "arguments": { "protocol": "vnc",
> -#  "fdname": "myclient" 
> } }
> -# <- { "return": {} }
> +# -> { "execute": "add_client", "arguments": { "protocol": "vnc",
> +#  "fdname": "myclient" } }
> +# <- { "return": {} }
>  ##
>  { 'command': 'add_client',
>'data': { 'protocol': 'str', 'fdname': 'str', '*skipauth': 'bool',
> @@ -142,7 +142,7 @@
>  # option was passed on the command line.
>  #
>  # In the "suspended" state, it will completely stop the VM and
> -# cause a transition to the "paused" state. (Since 9.0)
> +# cause a transition to the "paused" state.  (Since 9.0)
>  #
>  # Example:
>  #

This hunk belongs to PATCH 11.




Re: [PATCH v8] arm/kvm: Enable support for KVM_ARM_VCPU_PMU_V3_FILTER

2024-03-24 Thread Shaoqin Huang

Hi Daniel,

Thanks for your reviewing. I see your comments in the v7.

I have some doubts about what you said about the QAPI. Do you want me to 
convert the current design into the QAPI parsing like the 
IOThreadVirtQueueMapping? And we need to add new json definition in the 
qapi/ directory?


Thanks,
Shaoqin

On 3/22/24 22:53, Daniel P. Berrangé wrote:

On Tue, Mar 12, 2024 at 03:48:49AM -0400, Shaoqin Huang wrote:

The KVM_ARM_VCPU_PMU_V3_FILTER provides the ability to let the VMM decide
which PMU events are provided to the guest. Add a new option
`kvm-pmu-filter` as -cpu sub-option to set the PMU Event Filtering.
Without the filter, all PMU events are exposed from host to guest by
default. The usage of the new sub-option can be found from the updated
document (docs/system/arm/cpu-features.rst).

Here is an example which shows how to use the PMU Event Filtering, when
we launch a guest by use kvm, add such command line:

   # qemu-system-aarch64 \
 -accel kvm \
 -cpu host,kvm-pmu-filter="D:0x11-0x11"


I mistakenly sent some comments to the older v7 (despite this v8 already
existing) about the design of this syntax So for linking up the threads:

  https://lists.nongnu.org/archive/html/qemu-devel/2024-03/msg04703.html

With regards,
Daniel


--
Shaoqin




Re: [PATCH] contrib/plugins/execlog: Fix compiler warning

2024-03-24 Thread Pierrick Bouvier

On 3/25/24 07:00, Xingtao Yao (Fujitsu) wrote:

Pete:
Thanks for your comment.

I also find a similar patch written by Pierrick: 
https://lore.kernel.org/qemu-devel/20240118032400.3762658-15-pierrick.bouv...@linaro.org/
but for some reason, the patch was not merged yet.

shall I need to continue tracking the fixes of this bug?



Hi Xingtao,

you're doing the right thing here. In my original patch, there was no 
consideration for backward compatibility, to the opposite of what you did.


Alex will be out for several weeks, so it might take some time to get 
this merged, but I'm definitely voting for this .


Pierrick


-Original Message-
From: Peter Maydell 
Sent: Friday, March 22, 2024 7:50 PM
To: Yao, Xingtao/姚 幸涛 
Cc: alex.ben...@linaro.org; erdn...@crans.org; ma.mando...@gmail.com;
pierrick.bouv...@linaro.org; qemu-devel@nongnu.org
Subject: Re: [PATCH] contrib/plugins/execlog: Fix compiler warning

On Wed, 20 Mar 2024 at 02:05, Yao Xingtao via 
wrote:


1. The g_pattern_match_string() is deprecated when glib2 version >= 2.70.
Use g_pattern_spec_match_string() instead to avoid this problem.

2. The type of second parameter in g_ptr_array_add() is
'gpointer' {aka 'void *'}, but the type of reg->name is 'const char*'.
Cast the type of reg->name to 'gpointer' to avoid this problem.

compiler warning message:
/root/qemu/contrib/plugins/execlog.c:330:17: warning:

‘g_pattern_match_string’

is deprecated: Use 'g_pattern_spec_match_string'
instead [-Wdeprecated-declarations]
   330 | if (g_pattern_match_string(pat, rd->name) ||
   | ^~
In file included from /usr/include/glib-2.0/glib.h:67,
  from /root/qemu/contrib/plugins/execlog.c:9:
/usr/include/glib-2.0/glib/gpattern.h:57:15: note: declared here
57 | gboolean  g_pattern_match_string   (GPatternSpec *pspec,
   |   ^~
/root/qemu/contrib/plugins/execlog.c:331:21: warning:

‘g_pattern_match_string’

is deprecated: Use 'g_pattern_spec_match_string'
instead [-Wdeprecated-declarations]
   331 | g_pattern_match_string(pat, rd_lower)) {
   | ^~
/usr/include/glib-2.0/glib/gpattern.h:57:15: note: declared here
57 | gboolean  g_pattern_match_string   (GPatternSpec *pspec,
   |   ^~
/root/qemu/contrib/plugins/execlog.c:339:63: warning: passing argument
2 of ‘g_ptr_array_add’ discards ‘const’ qualifier from pointer target
type [-Wdiscarded-qualifiers]
   339 | g_ptr_array_add(all_reg_names,

reg->name);

   |

~~~^~

In file included from /usr/include/glib-2.0/glib.h:33:
/usr/include/glib-2.0/glib/garray.h:198:62: note: expected ‘gpointer’
{aka ‘void *’} but argument is of type ‘const char *’
   198 |gpointer

data);

   |

~~^~~~




Hi; thanks for this patch.

This fixes a bug reported in the bug tracker so we should put

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2210

in the commit message just above your signed-off-by tag.



Signed-off-by: Yao Xingtao 

I will if needed.


---
  contrib/plugins/execlog.c | 7 ++-
  1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
index a1dfd59ab7..41f6774116 100644
--- a/contrib/plugins/execlog.c
+++ b/contrib/plugins/execlog.c
@@ -327,8 +327,13 @@ static GPtrArray *registers_init(int vcpu_index)
  for (int p = 0; p < rmatches->len; p++) {
  g_autoptr(GPatternSpec) pat =

g_pattern_spec_new(rmatches->pdata[p]);

  g_autofree gchar *rd_lower = g_utf8_strdown(rd->name,
-1);
+#if GLIB_VERSION_MAX_ALLOWED < G_ENCODE_VERSION(2, 70)


Elsewhere we do glib version checks with

#if GLIB_CHECK_VERSION(2, 70, 0)
 code for 2.70.0 and up;
#else
 code for older versions
#endif

so I think we should probably do that here too.


  if (g_pattern_match_string(pat, rd->name) ||
  g_pattern_match_string(pat, rd_lower)) {
+#else
+if (g_pattern_spec_match_string(pat, rd->name) ||
+g_pattern_spec_match_string(pat, rd_lower)) {
+#endif

thanks, I got it.



Rather than putting this ifdef in the middle of this function, I think it would 
be
easier to read if we abstract out a function which does the pattern matching
and whose body calls the right glib function depending on glib version. We
generally call these functions the same as the glib function but with a _qemu
suffix (compare the ones in include/glib-compat.h), so here that would be
g_pattern_spec_match_string_qemu().


  Register *reg = init_vcpu_register(rd);
  g_ptr_array_add(registers, reg);

@@ -336,7 +341,7 @@ static GPtrArray *registers_init(int vcpu_index)
  if (disas_assist) {
  

[PATCH 3/3] target/hppa: Fix unit carry conditions

2024-03-24 Thread Richard Henderson
Split do_unit_cond to do_unit_zero_cond to only handle
conditions versus zero.  These are the only ones that
are legal for UXOR.  Simplify trans_uxor accordingly.

Rename do_unit to do_unit_addsub, since xor has been split.
Properly compute carry-out bits for add and subtract,
mirroring the code in do_add and do_sub.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 214 
 1 file changed, 109 insertions(+), 105 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 3fc3e7754c..2bf213c938 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -936,98 +936,44 @@ static DisasCond do_sed_cond(DisasContext *ctx, unsigned 
orig, bool d,
 return do_log_cond(ctx, c * 2 + f, d, res);
 }
 
-/* Similar, but for unit conditions.  */
-
-static DisasCond do_unit_cond(unsigned cf, bool d, TCGv_i64 res,
-  TCGv_i64 in1, TCGv_i64 in2)
+/* Similar, but for unit zero conditions.  */
+static DisasCond do_unit_zero_cond(unsigned cf, bool d, TCGv_i64 res)
 {
-DisasCond cond;
-TCGv_i64 tmp, cb = NULL;
+TCGv_i64 tmp;
 uint64_t d_repl = d ? 0x00010001ull : 1;
-
-if (cf & 8) {
-/* Since we want to test lots of carry-out bits all at once, do not
- * do our normal thing and compute carry-in of bit B+1 since that
- * leaves us with carry bits spread across two words.
- */
-cb = tcg_temp_new_i64();
-tmp = tcg_temp_new_i64();
-tcg_gen_or_i64(cb, in1, in2);
-tcg_gen_and_i64(tmp, in1, in2);
-tcg_gen_andc_i64(cb, cb, res);
-tcg_gen_or_i64(cb, cb, tmp);
-}
+uint64_t ones = 0, sgns = 0;
 
 switch (cf >> 1) {
-case 0: /* never / TR */
-cond = cond_make_f();
-break;
-
 case 1: /* SBW / NBW */
 if (d) {
-tmp = tcg_temp_new_i64();
-tcg_gen_subi_i64(tmp, res, d_repl * 0x0001u);
-tcg_gen_andc_i64(tmp, tmp, res);
-tcg_gen_andi_i64(tmp, tmp, d_repl * 0x8000u);
-cond = cond_make_0(TCG_COND_NE, tmp);
-} else {
-/* undefined */
-cond = cond_make_f();
+ones = d_repl;
+sgns = d_repl << 31;
 }
 break;
-
 case 2: /* SBZ / NBZ */
-/* See hasless(v,1) from
- * https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
- */
-tmp = tcg_temp_new_i64();
-tcg_gen_subi_i64(tmp, res, d_repl * 0x01010101u);
-tcg_gen_andc_i64(tmp, tmp, res);
-tcg_gen_andi_i64(tmp, tmp, d_repl * 0x80808080u);
-cond = cond_make_0(TCG_COND_NE, tmp);
+ones = d_repl * 0x01010101u;
+sgns = ones << 7;
 break;
-
 case 3: /* SHZ / NHZ */
-tmp = tcg_temp_new_i64();
-tcg_gen_subi_i64(tmp, res, d_repl * 0x00010001u);
-tcg_gen_andc_i64(tmp, tmp, res);
-tcg_gen_andi_i64(tmp, tmp, d_repl * 0x80008000u);
-cond = cond_make_0(TCG_COND_NE, tmp);
+ones = d_repl * 0x00010001u;
+sgns = ones << 15;
 break;
-
-case 4: /* SDC / NDC */
-tcg_gen_andi_i64(cb, cb, d_repl * 0xu);
-cond = cond_make_0(TCG_COND_NE, cb);
-break;
-
-case 5: /* SWC / NWC */
-if (d) {
-tcg_gen_andi_i64(cb, cb, d_repl * 0x8000u);
-cond = cond_make_0(TCG_COND_NE, cb);
-} else {
-/* undefined */
-cond = cond_make_f();
-}
-break;
-
-case 6: /* SBC / NBC */
-tcg_gen_andi_i64(cb, cb, d_repl * 0x80808080u);
-cond = cond_make_0(TCG_COND_NE, cb);
-break;
-
-case 7: /* SHC / NHC */
-tcg_gen_andi_i64(cb, cb, d_repl * 0x80008000u);
-cond = cond_make_0(TCG_COND_NE, cb);
-break;
-
-default:
-g_assert_not_reached();
 }
-if (cf & 1) {
-cond.c = tcg_invert_cond(cond.c);
+if (ones == 0) {
+/* Undefined, or 0/1 (never/always). */
+return cf & 1 ? cond_make_t() : cond_make_f();
 }
 
-return cond;
+/*
+ * See hasless(v,1) from
+ * https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
+ */
+tmp = tcg_temp_new_i64();
+tcg_gen_subi_i64(tmp, res, ones);
+tcg_gen_andc_i64(tmp, tmp, res);
+
+return cond_make_tmp(cf & 1 ? TCG_COND_TSTEQ : TCG_COND_TSTNE,
+ tmp, tcg_constant_i64(sgns));
 }
 
 static TCGv_i64 get_carry(DisasContext *ctx, bool d,
@@ -1330,34 +1276,82 @@ static bool do_log_reg(DisasContext *ctx, arg_rrr_cf_d 
*a,
 return nullify_end(ctx);
 }
 
-static void do_unit(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
-TCGv_i64 in2, unsigned cf, bool d, bool is_tc,
-void (*fn)(TCGv_i64, TCGv_i64, TCGv_i64))
+static void do_unit_addsub(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
+   TCGv_i64 in2, unsigned cf, bool d,
+  

[PATCH 2/3] target/hppa: Optimize UADDCM with no condition

2024-03-24 Thread Richard Henderson
With r1 as zero is by far the only usage of UADDCM, as the easiest
way to invert a register.  The compiler does occasionally use the
addition step as well, and we can simplify that to avoid a temp
and write directly into the destination.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 24 ++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index a3f425d861..3fc3e7754c 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2763,9 +2763,29 @@ static bool do_uaddcm(DisasContext *ctx, arg_rrr_cf_d 
*a, bool is_tc)
 {
 TCGv_i64 tcg_r1, tcg_r2, tmp;
 
-if (a->cf) {
-nullify_over(ctx);
+if (a->cf == 0) {
+tcg_r2 = load_gpr(ctx, a->r2);
+tmp = dest_gpr(ctx, a->t);
+
+if (a->r1 == 0) {
+/* UADDCM r0,src,dst is the common idiom for dst = ~src. */
+tcg_gen_not_i64(tmp, tcg_r2);
+} else {
+/*
+ * Recall that r1 - r2 == r1 + ~r2 + 1.
+ * Thus r1 + ~r2 == r1 - r2 - 1,
+ * which does not require an extra temporary.
+ */
+tcg_r1 = load_gpr(ctx, a->r1);
+tcg_gen_sub_i64(tmp, tcg_r1, tcg_r2);
+tcg_gen_subi_i64(tmp, tmp, 1);
+}
+save_gpr(ctx, a->t, tmp);
+cond_free(>null_cond);
+return true;
 }
+
+nullify_over(ctx);
 tcg_r1 = load_gpr(ctx, a->r1);
 tcg_r2 = load_gpr(ctx, a->r2);
 tmp = tcg_temp_new_i64();
-- 
2.34.1




[PATCH for-9.0 0/3] target/hppa: Fix DCOR, UADDCM conditions

2024-03-24 Thread Richard Henderson
Two problems, both related to the reconstruction and computation
of carry bits.  Simplify UXOR a bit, since no carry is involved.
While in the area, optimize UADDCM without condition, as that's
the common case for inverting a register.


r~


Richard Henderson (3):
  targt/hppa: Fix DCOR reconstruction of carry bits
  target/hppa: Optimize UADDCM with no condition
  target/hppa: Fix unit carry conditions

 target/hppa/translate.c | 240 ++--
 1 file changed, 132 insertions(+), 108 deletions(-)

-- 
2.34.1




[PATCH 1/3] targt/hppa: Fix DCOR reconstruction of carry bits

2024-03-24 Thread Richard Henderson
The carry bits for each nibble N are located in bit (N+1)*4,
so the shift by 3 was off by one.  Furthermore, the carry bit
for the most significant carry bit is indeed located in bit 64,
which is located in a different storage word.

Use a double-word shift-right to reassemble into a single word
and place them all at bit 0 of their respective nibbles.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index e041310207..a3f425d861 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2791,7 +2791,7 @@ static bool do_dcor(DisasContext *ctx, arg_rr_cf_d *a, 
bool is_i)
 nullify_over(ctx);
 
 tmp = tcg_temp_new_i64();
-tcg_gen_shri_i64(tmp, cpu_psw_cb, 3);
+tcg_gen_extract2_i64(tmp, cpu_psw_cb, cpu_psw_cb_msb, 4);
 if (!is_i) {
 tcg_gen_not_i64(tmp, tmp);
 }
-- 
2.34.1




RE: [PATCH] contrib/plugins/execlog: Fix compiler warning

2024-03-24 Thread Xingtao Yao (Fujitsu)
Pete:
Thanks for your comment.

I also find a similar patch written by Pierrick: 
https://lore.kernel.org/qemu-devel/20240118032400.3762658-15-pierrick.bouv...@linaro.org/
but for some reason, the patch was not merged yet.

shall I need to continue tracking the fixes of this bug?

> -Original Message-
> From: Peter Maydell 
> Sent: Friday, March 22, 2024 7:50 PM
> To: Yao, Xingtao/姚 幸涛 
> Cc: alex.ben...@linaro.org; erdn...@crans.org; ma.mando...@gmail.com;
> pierrick.bouv...@linaro.org; qemu-devel@nongnu.org
> Subject: Re: [PATCH] contrib/plugins/execlog: Fix compiler warning
> 
> On Wed, 20 Mar 2024 at 02:05, Yao Xingtao via 
> wrote:
> >
> > 1. The g_pattern_match_string() is deprecated when glib2 version >= 2.70.
> >Use g_pattern_spec_match_string() instead to avoid this problem.
> >
> > 2. The type of second parameter in g_ptr_array_add() is
> >'gpointer' {aka 'void *'}, but the type of reg->name is 'const char*'.
> >Cast the type of reg->name to 'gpointer' to avoid this problem.
> >
> > compiler warning message:
> > /root/qemu/contrib/plugins/execlog.c:330:17: warning:
> ‘g_pattern_match_string’
> > is deprecated: Use 'g_pattern_spec_match_string'
> > instead [-Wdeprecated-declarations]
> >   330 | if (g_pattern_match_string(pat, rd->name) ||
> >   | ^~
> > In file included from /usr/include/glib-2.0/glib.h:67,
> >  from /root/qemu/contrib/plugins/execlog.c:9:
> > /usr/include/glib-2.0/glib/gpattern.h:57:15: note: declared here
> >57 | gboolean  g_pattern_match_string   (GPatternSpec *pspec,
> >   |   ^~
> > /root/qemu/contrib/plugins/execlog.c:331:21: warning:
> ‘g_pattern_match_string’
> > is deprecated: Use 'g_pattern_spec_match_string'
> > instead [-Wdeprecated-declarations]
> >   331 | g_pattern_match_string(pat, rd_lower)) {
> >   | ^~
> > /usr/include/glib-2.0/glib/gpattern.h:57:15: note: declared here
> >57 | gboolean  g_pattern_match_string   (GPatternSpec *pspec,
> >   |   ^~
> > /root/qemu/contrib/plugins/execlog.c:339:63: warning: passing argument
> > 2 of ‘g_ptr_array_add’ discards ‘const’ qualifier from pointer target
> > type [-Wdiscarded-qualifiers]
> >   339 | g_ptr_array_add(all_reg_names,
> reg->name);
> >   |
> ~~~^~
> > In file included from /usr/include/glib-2.0/glib.h:33:
> > /usr/include/glib-2.0/glib/garray.h:198:62: note: expected ‘gpointer’
> > {aka ‘void *’} but argument is of type ‘const char *’
> >   198 |gpointer
> data);
> >   |
> ~~^~~~
> >
> 
> Hi; thanks for this patch.
> 
> This fixes a bug reported in the bug tracker so we should put
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2210
> 
> in the commit message just above your signed-off-by tag.
> 
> 
> > Signed-off-by: Yao Xingtao 
I will if needed.

> > ---
> >  contrib/plugins/execlog.c | 7 ++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> >
> > diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
> > index a1dfd59ab7..41f6774116 100644
> > --- a/contrib/plugins/execlog.c
> > +++ b/contrib/plugins/execlog.c
> > @@ -327,8 +327,13 @@ static GPtrArray *registers_init(int vcpu_index)
> >  for (int p = 0; p < rmatches->len; p++) {
> >  g_autoptr(GPatternSpec) pat =
> g_pattern_spec_new(rmatches->pdata[p]);
> >  g_autofree gchar *rd_lower = g_utf8_strdown(rd->name,
> > -1);
> > +#if GLIB_VERSION_MAX_ALLOWED < G_ENCODE_VERSION(2, 70)
> 
> Elsewhere we do glib version checks with
> 
> #if GLIB_CHECK_VERSION(2, 70, 0)
> code for 2.70.0 and up;
> #else
> code for older versions
> #endif
> 
> so I think we should probably do that here too.
> 
> >  if (g_pattern_match_string(pat, rd->name) ||
> >  g_pattern_match_string(pat, rd_lower)) {
> > +#else
> > +if (g_pattern_spec_match_string(pat, rd->name) ||
> > +g_pattern_spec_match_string(pat, rd_lower)) {
> > +#endif
thanks, I got it.

> 
> Rather than putting this ifdef in the middle of this function, I think it 
> would be
> easier to read if we abstract out a function which does the pattern matching
> and whose body calls the right glib function depending on glib version. We
> generally call these functions the same as the glib function but with a _qemu
> suffix (compare the ones in include/glib-compat.h), so here that would be
> g_pattern_spec_match_string_qemu().
> 
> >  Register *reg = init_vcpu_register(rd);
> >  g_ptr_array_add(registers, reg);
> >
> > @@ -336,7 +341,7 @@ static GPtrArray *registers_init(int vcpu_index)
> >  if (disas_assist) {
> >  g_mutex_lock(_reg_name_lock);
> > 

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

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

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

Signed-off-by: Huang Tao 
Suggested-by: Richard Henderson 
Reviewed-by: LIU Zhiwei 
---
Changes in v3:
- use "if (HOST_BIG_ENDIAN)" instead of "#if HOST_BIG_ENDIAN"

Changes in v2:
- Keep the api of vext_set_elems_1s
- Reduce the number of patches.
---
 target/riscv/vector_internals.c | 22 ++
 1 file changed, 22 insertions(+)

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




Re: [PATCH-for-9.1 05/21] target/m68k: Replace qemu_printf() by monitor_printf() in monitor

2024-03-24 Thread BALATON Zoltan

On Sun, 24 Mar 2024, Dr. David Alan Gilbert wrote:

* Philippe Mathieu-Daudé (phi...@linaro.org) wrote:

Replace qemu_printf() by monitor_printf() / monitor_puts() in monitor.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/m68k/cpu.h |   2 +-
 target/m68k/helper.c  | 126 +-
 target/m68k/monitor.c |   4 +-
 3 files changed, 67 insertions(+), 65 deletions(-)

diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 346427e144..4e4307956d 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -620,6 +620,6 @@ static inline void cpu_get_tb_cpu_state(CPUM68KState *env, 
vaddr *pc,
 }
 }

-void dump_mmu(CPUM68KState *env);
+void dump_mmu(Monitor *mon, CPUM68KState *env);

 #endif
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index 1a475f082a..310e26dfa1 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -25,7 +25,7 @@
 #include "exec/helper-proto.h"
 #include "gdbstub/helpers.h"
 #include "fpu/softfloat.h"
-#include "qemu/qemu-print.h"
+#include "monitor/monitor.h"

 #define SIGNBIT (1u << 31)

@@ -455,28 +455,30 @@ void m68k_switch_sp(CPUM68KState *env)
 #if !defined(CONFIG_USER_ONLY)
 /* MMU: 68040 only */

-static void print_address_zone(uint32_t logical, uint32_t physical,
+static void print_address_zone(Monitor *mon,
+   uint32_t logical, uint32_t physical,
uint32_t size, int attr)
 {
-qemu_printf("%08x - %08x -> %08x - %08x %c ",
-logical, logical + size - 1,
-physical, physical + size - 1,
-attr & 4 ? 'W' : '-');
+monitor_printf(mon, "%08x - %08x -> %08x - %08x %c ",
+   logical, logical + size - 1,
+   physical, physical + size - 1,
+   attr & 4 ? 'W' : '-');
 size >>= 10;
 if (size < 1024) {
-qemu_printf("(%d KiB)\n", size);
+monitor_printf(mon, "(%d KiB)\n", size);
 } else {
 size >>= 10;
 if (size < 1024) {
-qemu_printf("(%d MiB)\n", size);
+monitor_printf(mon, "(%d MiB)\n", size);
 } else {
 size >>= 10;
-qemu_printf("(%d GiB)\n", size);
+monitor_printf(mon, "(%d GiB)\n", size);
 }
 }
 }

-static void dump_address_map(CPUM68KState *env, uint32_t root_pointer)
+static void dump_address_map(Monitor *mon, CPUM68KState *env,
+ uint32_t root_pointer)
 {
 int i, j, k;
 int tic_size, tic_shift;
@@ -545,7 +547,7 @@ static void dump_address_map(CPUM68KState *env, uint32_t 
root_pointer)
 if (first_logical != 0x) {
 size = last_logical + (1 << tic_shift) -
first_logical;
-print_address_zone(first_logical,
+print_address_zone(mon, first_logical,
first_physical, size, last_attr);
 }
 first_logical = logical;
@@ -556,125 +558,125 @@ static void dump_address_map(CPUM68KState *env, 
uint32_t root_pointer)
 }
 if (first_logical != logical || (attr & 4) != (last_attr & 4)) {
 size = logical + (1 << tic_shift) - first_logical;
-print_address_zone(first_logical, first_physical, size, last_attr);
+print_address_zone(mon, first_logical, first_physical, size, 
last_attr);
 }
 }

 #define DUMP_CACHEFLAGS(a) \
 switch (a & M68K_DESC_CACHEMODE) { \
 case M68K_DESC_CM_WRTHRU: /* cacheable, write-through */ \
-qemu_printf("T"); \
+monitor_puts(mon, "T"); \
 break; \
 case M68K_DESC_CM_COPYBK: /* cacheable, copyback */ \
-qemu_printf("C"); \
+monitor_puts(mon, "C"); \
 break; \
 case M68K_DESC_CM_SERIAL: /* noncachable, serialized */ \
-qemu_printf("S"); \
+monitor_puts(mon, "S"); \
 break; \
 case M68K_DESC_CM_NCACHE: /* noncachable */ \
-qemu_printf("N"); \
+monitor_puts(mon, "N"); \
 break; \
 }

-static void dump_ttr(uint32_t ttr)
+static void dump_ttr(Monitor *mon, uint32_t ttr)
 {
 if ((ttr & M68K_TTR_ENABLED) == 0) {
-qemu_printf("disabled\n");
+monitor_puts(mon, "disabled\n");
 return;
 }
-qemu_printf("Base: 0x%08x Mask: 0x%08x Control: ",
-ttr & M68K_TTR_ADDR_BASE,
-(ttr & M68K_TTR_ADDR_MASK) << M68K_TTR_ADDR_MASK_SHIFT);
+monitor_printf(mon, "Base: 0x%08x Mask: 0x%08x Control: ",
+   ttr & M68K_TTR_ADDR_BASE,
+   (ttr & M68K_TTR_ADDR_MASK) << M68K_TTR_ADDR_MASK_SHIFT);
 switch (ttr & M68K_TTR_SFIELD) {
 case M68K_TTR_SFIELD_USER:
-qemu_printf("U");
+monitor_puts(mon, "U");
 break;
 case M68K_TTR_SFIELD_SUPER:
-qemu_printf("S");
+monitor_puts(mon, "S");
 break;
 default:
-

Re: [PATCH v4 0/2] Add support for LAM in QEMU

2024-03-24 Thread Binbin Wu



Ping...

On 1/22/2024 4:55 PM, Binbin Wu wrote:

Gentle ping...
Please help to review and consider applying the patch series. (The KVM
part has been merged).


On 1/12/2024 2:00 PM, Binbin Wu wrote:
Linear-address masking (LAM) [1], modifies the checking that is 
applied to

*64-bit* linear addresses, allowing software to use of the untranslated
address bits for metadata and masks the metadata bits before using 
them as

linear addresses to access memory.

When the feature is virtualized and exposed to guest, it can be used for
efficient
address sanitizers (ASAN) implementation and for optimizations in 
JITs and

virtual machines.

The KVM patch series can be found in [2].

[1] Intel ISE https://cdrdv2.intel.com/v1/dl/getContent/671368
 Chapter Linear Address Masking (LAM)
[2] 
https://lore.kernel.org/kvm/20230913124227.12574-1-binbin...@linux.intel.com


---
Changelog
v4:
- Add a reviewed-by from Xiaoyao for patch 1.
- Mask out LAM bit on CR4 if vcpu doesn't support LAM in 
cpu_x86_update_cr4() (Xiaoyao)


v3:
- https://lists.gnu.org/archive/html/qemu-devel/2023-07/msg04160.html

Binbin Wu (1):
   target/i386: add control bits support for LAM

Robert Hoo (1):
   target/i386: add support for LAM in CPUID enumeration

  target/i386/cpu.c    | 2 +-
  target/i386/cpu.h    | 9 -
  target/i386/helper.c | 4 
  3 files changed, 13 insertions(+), 2 deletions(-)


base-commit: f614acb7450282a119d85d759f27eae190476058







Re: [PATCH-for-9.1 05/21] target/m68k: Replace qemu_printf() by monitor_printf() in monitor

2024-03-24 Thread Dr. David Alan Gilbert
* Philippe Mathieu-Daudé (phi...@linaro.org) wrote:
> Replace qemu_printf() by monitor_printf() / monitor_puts() in monitor.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/m68k/cpu.h |   2 +-
>  target/m68k/helper.c  | 126 +-
>  target/m68k/monitor.c |   4 +-
>  3 files changed, 67 insertions(+), 65 deletions(-)
> 
> diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
> index 346427e144..4e4307956d 100644
> --- a/target/m68k/cpu.h
> +++ b/target/m68k/cpu.h
> @@ -620,6 +620,6 @@ static inline void cpu_get_tb_cpu_state(CPUM68KState 
> *env, vaddr *pc,
>  }
>  }
>  
> -void dump_mmu(CPUM68KState *env);
> +void dump_mmu(Monitor *mon, CPUM68KState *env);
>  
>  #endif
> diff --git a/target/m68k/helper.c b/target/m68k/helper.c
> index 1a475f082a..310e26dfa1 100644
> --- a/target/m68k/helper.c
> +++ b/target/m68k/helper.c
> @@ -25,7 +25,7 @@
>  #include "exec/helper-proto.h"
>  #include "gdbstub/helpers.h"
>  #include "fpu/softfloat.h"
> -#include "qemu/qemu-print.h"
> +#include "monitor/monitor.h"
>  
>  #define SIGNBIT (1u << 31)
>  
> @@ -455,28 +455,30 @@ void m68k_switch_sp(CPUM68KState *env)
>  #if !defined(CONFIG_USER_ONLY)
>  /* MMU: 68040 only */
>  
> -static void print_address_zone(uint32_t logical, uint32_t physical,
> +static void print_address_zone(Monitor *mon,
> +   uint32_t logical, uint32_t physical,
> uint32_t size, int attr)
>  {
> -qemu_printf("%08x - %08x -> %08x - %08x %c ",
> -logical, logical + size - 1,
> -physical, physical + size - 1,
> -attr & 4 ? 'W' : '-');
> +monitor_printf(mon, "%08x - %08x -> %08x - %08x %c ",
> +   logical, logical + size - 1,
> +   physical, physical + size - 1,
> +   attr & 4 ? 'W' : '-');
>  size >>= 10;
>  if (size < 1024) {
> -qemu_printf("(%d KiB)\n", size);
> +monitor_printf(mon, "(%d KiB)\n", size);
>  } else {
>  size >>= 10;
>  if (size < 1024) {
> -qemu_printf("(%d MiB)\n", size);
> +monitor_printf(mon, "(%d MiB)\n", size);
>  } else {
>  size >>= 10;
> -qemu_printf("(%d GiB)\n", size);
> +monitor_printf(mon, "(%d GiB)\n", size);
>  }
>  }
>  }
>  
> -static void dump_address_map(CPUM68KState *env, uint32_t root_pointer)
> +static void dump_address_map(Monitor *mon, CPUM68KState *env,
> + uint32_t root_pointer)
>  {
>  int i, j, k;
>  int tic_size, tic_shift;
> @@ -545,7 +547,7 @@ static void dump_address_map(CPUM68KState *env, uint32_t 
> root_pointer)
>  if (first_logical != 0x) {
>  size = last_logical + (1 << tic_shift) -
> first_logical;
> -print_address_zone(first_logical,
> +print_address_zone(mon, first_logical,
> first_physical, size, last_attr);
>  }
>  first_logical = logical;
> @@ -556,125 +558,125 @@ static void dump_address_map(CPUM68KState *env, 
> uint32_t root_pointer)
>  }
>  if (first_logical != logical || (attr & 4) != (last_attr & 4)) {
>  size = logical + (1 << tic_shift) - first_logical;
> -print_address_zone(first_logical, first_physical, size, last_attr);
> +print_address_zone(mon, first_logical, first_physical, size, 
> last_attr);
>  }
>  }
>  
>  #define DUMP_CACHEFLAGS(a) \
>  switch (a & M68K_DESC_CACHEMODE) { \
>  case M68K_DESC_CM_WRTHRU: /* cacheable, write-through */ \
> -qemu_printf("T"); \
> +monitor_puts(mon, "T"); \
>  break; \
>  case M68K_DESC_CM_COPYBK: /* cacheable, copyback */ \
> -qemu_printf("C"); \
> +monitor_puts(mon, "C"); \
>  break; \
>  case M68K_DESC_CM_SERIAL: /* noncachable, serialized */ \
> -qemu_printf("S"); \
> +monitor_puts(mon, "S"); \
>  break; \
>  case M68K_DESC_CM_NCACHE: /* noncachable */ \
> -qemu_printf("N"); \
> +monitor_puts(mon, "N"); \
>  break; \
>  }
>  
> -static void dump_ttr(uint32_t ttr)
> +static void dump_ttr(Monitor *mon, uint32_t ttr)
>  {
>  if ((ttr & M68K_TTR_ENABLED) == 0) {
> -qemu_printf("disabled\n");
> +monitor_puts(mon, "disabled\n");
>  return;
>  }
> -qemu_printf("Base: 0x%08x Mask: 0x%08x Control: ",
> -ttr & M68K_TTR_ADDR_BASE,
> -(ttr & M68K_TTR_ADDR_MASK) << M68K_TTR_ADDR_MASK_SHIFT);
> +monitor_printf(mon, "Base: 0x%08x Mask: 0x%08x Control: ",
> +   ttr & M68K_TTR_ADDR_BASE,
> +   (ttr & M68K_TTR_ADDR_MASK) << M68K_TTR_ADDR_MASK_SHIFT);
>  switch (ttr & M68K_TTR_SFIELD) {
>  case M68K_TTR_SFIELD_USER:
> 

Re: [PATCH 3/3] target/hppa: fix building gva for wide mode

2024-03-24 Thread Richard Henderson

On 3/24/24 11:39, Richard Henderson wrote:

On 3/23/24 22:09, Sven Schnelle wrote:

64 Bit hppa no longer has a fixed 32/32 bit split between space and
offset. Instead it uses 42 bits for the offset. The lower 10 bits of
the space are always zero, leaving 22 bits actually used. Simply or
the values together to build the gva.

Signed-off-by: Sven Schnelle 
---
  target/hppa/mem_helper.c | 13 +++--
  1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 84785b5a5c..6f895fced7 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -523,13 +523,16 @@ void HELPER(itlbp_pa11)(CPUHPPAState *env, target_ulong addr, 
target_ulong reg)

  }
  static void itlbt_pa20(CPUHPPAState *env, target_ulong r1,
-   target_ulong r2, vaddr va_b)
+   target_ulong r2, uint64_t spc, uint64_t off)
  {
  HPPATLBEntry *ent;
-    vaddr va_e;
+    vaddr va_b, va_e;
  uint64_t va_size;
  int mask_shift;
+    va_b = off & gva_offset_mask(env->psw);
+    va_b |= spc << 32;


Actually, no, these instructions don't form a GVA in the normal fashion:

space ← ISR;
offset ← cat(ISR{32..63},IOR{32..63});
VIRTUAL_ADDR ← (space<<32) | (offset);


-    vaddr va_b = deposit64(env->cr[CR_IOR], 32, 32, env->cr[CR_ISR]);


But this is wrong too.


Actually, no.  The

  VIRTUAL_ADDR = (space << 32) | offset

line constructs a 96-bit virtual address.  The low 32 bits of ISR have already replaced 
the high 32 bits of IOR, so this line really only adds the high 32 bits of space as bits 
[96:64] of the full virtual address.


Truncated to 64 bits, the deposit as written is exactly right.


r~



Re: [PATCH 2/3] target/hppa: mask offset bits in gva

2024-03-24 Thread Richard Henderson

On 3/24/24 08:41, Sven Schnelle wrote:

7f09e0: val=000fffb0301f r2=110e0f01 r1=01fff600 
phys=fffb 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)

'val' is the value constructed from IOR/ISR,


Is this byte swapped in some weird way?  I do not see how 'val' corresponds to any of the 
addresses we're talking about.  From here, the string "301f" appears to an 
out-of-context grep hit.



r~



Re: [PATCH 3/3] target/hppa: fix building gva for wide mode

2024-03-24 Thread Richard Henderson

On 3/23/24 22:09, Sven Schnelle wrote:

64 Bit hppa no longer has a fixed 32/32 bit split between space and
offset. Instead it uses 42 bits for the offset. The lower 10 bits of
the space are always zero, leaving 22 bits actually used. Simply or
the values together to build the gva.

Signed-off-by: Sven Schnelle 
---
  target/hppa/mem_helper.c | 13 +++--
  1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 84785b5a5c..6f895fced7 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -523,13 +523,16 @@ void HELPER(itlbp_pa11)(CPUHPPAState *env, target_ulong 
addr, target_ulong reg)
  }
  
  static void itlbt_pa20(CPUHPPAState *env, target_ulong r1,

-   target_ulong r2, vaddr va_b)
+   target_ulong r2, uint64_t spc, uint64_t off)
  {
  HPPATLBEntry *ent;
-vaddr va_e;
+vaddr va_b, va_e;
  uint64_t va_size;
  int mask_shift;
  
+va_b = off & gva_offset_mask(env->psw);

+va_b |= spc << 32;


Actually, no, these instructions don't form a GVA in the normal fashion:

space ← ISR;
offset ← cat(ISR{32..63},IOR{32..63});
VIRTUAL_ADDR ← (space<<32) | (offset);


-vaddr va_b = deposit64(env->cr[CR_IOR], 32, 32, env->cr[CR_ISR]);


But this is wrong too.

Since the input here is from the result of a previous memory access, which populated 
ISR+IOR, I presume any masking would be done from the prior memory access.


We do need to fix the merge, per the docs though.


r~



Re: [PATCH] docs/system/ppc/amigang.rst: Fix formatting

2024-03-24 Thread Peter Maydell
On Sun, 24 Mar 2024 at 16:13, BALATON Zoltan  wrote:
>
> Add missing space to fix character formatting where it was missed in
> two places.
>
> Fixes: 623d9065b6 (docs/system/ppc: Document running Linux on AmigaNG 
> machines)
> Signed-off-by: BALATON Zoltan 
> ---
Reviewed-by: Peter Maydell 

thanks
-- PMM



[PATCH v3 10/17] esp.c: don't assert() if FIFO empty when executing non-DMA SELATNS

2024-03-24 Thread Mark Cave-Ayland
The current logic assumes that at least 1 byte is present in the FIFO when
executing a non-DMA SELATNS command, but this may not be the case if the
guest executes an invalid ESP command sequence.

Reported-by: Chuhong Yuan 
Signed-off-by: Mark Cave-Ayland 
---
 hw/scsi/esp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 1aac8f5564..f3aa5364cf 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -762,7 +762,8 @@ static void esp_do_nodma(ESPState *s)
 
 case CMD_SELATNS:
 /* Copy one byte from FIFO into cmdfifo */
-len = esp_fifo_pop_buf(s, buf, 1);
+len = esp_fifo_pop_buf(s, buf,
+   MIN(fifo8_num_used(>fifo), 1));
 len = MIN(fifo8_num_free(>cmdfifo), len);
 fifo8_push_all(>cmdfifo, buf, len);
 
-- 
2.39.2




[PATCH v3 02/17] esp.c: replace esp_fifo_pop_buf() with esp_fifo8_pop_buf() in do_command_phase()

2024-03-24 Thread Mark Cave-Ayland
The aim is to restrict the esp_fifo_*() functions so that they only operate on
the hardware FIFO. When reading from cmdfifo in do_command_phase() use the
underlying esp_fifo8_pop_buf() function directly.

Signed-off-by: Mark Cave-Ayland 
---
 hw/scsi/esp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 1b7b118a0b..ff51145da7 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -280,7 +280,7 @@ static void do_command_phase(ESPState *s)
 if (!cmdlen || !s->current_dev) {
 return;
 }
-esp_fifo_pop_buf(>cmdfifo, buf, cmdlen);
+esp_fifo8_pop_buf(>cmdfifo, buf, cmdlen);
 
 current_lun = scsi_device_find(>bus, 0, s->current_dev->id, s->lun);
 if (!current_lun) {
-- 
2.39.2




[PATCH v3 08/17] esp.c: change esp_fifo_pop_buf() to take ESPState

2024-03-24 Thread Mark Cave-Ayland
Now that all users of esp_fifo_pop_buf() operate on the main FIFO there is no
need to pass the FIFO explicitly.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/scsi/esp.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 8d2d36d56c..83b621ee0f 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -155,9 +155,9 @@ static uint32_t esp_fifo8_pop_buf(Fifo8 *fifo, uint8_t 
*dest, int maxlen)
 return n;
 }
 
-static uint32_t esp_fifo_pop_buf(Fifo8 *fifo, uint8_t *dest, int maxlen)
+static uint32_t esp_fifo_pop_buf(ESPState *s, uint8_t *dest, int maxlen)
 {
-return esp_fifo8_pop_buf(fifo, dest, maxlen);
+return esp_fifo8_pop_buf(>fifo, dest, maxlen);
 }
 
 static uint32_t esp_get_tc(ESPState *s)
@@ -459,7 +459,7 @@ static void esp_do_dma(ESPState *s)
 s->dma_memory_read(s->dma_opaque, buf, len);
 esp_set_tc(s, esp_get_tc(s) - len);
 } else {
-len = esp_fifo_pop_buf(>fifo, buf, fifo8_num_used(>fifo));
+len = esp_fifo_pop_buf(s, buf, fifo8_num_used(>fifo));
 len = MIN(fifo8_num_free(>cmdfifo), len);
 esp_raise_drq(s);
 }
@@ -515,7 +515,7 @@ static void esp_do_dma(ESPState *s)
 fifo8_push_all(>cmdfifo, buf, len);
 esp_set_tc(s, esp_get_tc(s) - len);
 } else {
-len = esp_fifo_pop_buf(>fifo, buf, fifo8_num_used(>fifo));
+len = esp_fifo_pop_buf(s, buf, fifo8_num_used(>fifo));
 len = MIN(fifo8_num_free(>cmdfifo), len);
 fifo8_push_all(>cmdfifo, buf, len);
 esp_raise_drq(s);
@@ -549,7 +549,7 @@ static void esp_do_dma(ESPState *s)
 /* Copy FIFO data to device */
 len = MIN(s->async_len, ESP_FIFO_SZ);
 len = MIN(len, fifo8_num_used(>fifo));
-len = esp_fifo_pop_buf(>fifo, s->async_buf, len);
+len = esp_fifo_pop_buf(s, s->async_buf, len);
 esp_raise_drq(s);
 }
 
@@ -713,7 +713,7 @@ static void esp_nodma_ti_dataout(ESPState *s)
 }
 len = MIN(s->async_len, ESP_FIFO_SZ);
 len = MIN(len, fifo8_num_used(>fifo));
-esp_fifo_pop_buf(>fifo, s->async_buf, len);
+esp_fifo_pop_buf(s, s->async_buf, len);
 s->async_buf += len;
 s->async_len -= len;
 s->ti_size += len;
@@ -738,7 +738,7 @@ static void esp_do_nodma(ESPState *s)
 switch (s->rregs[ESP_CMD]) {
 case CMD_SELATN:
 /* Copy FIFO into cmdfifo */
-len = esp_fifo_pop_buf(>fifo, buf, fifo8_num_used(>fifo));
+len = esp_fifo_pop_buf(s, buf, fifo8_num_used(>fifo));
 len = MIN(fifo8_num_free(>cmdfifo), len);
 fifo8_push_all(>cmdfifo, buf, len);
 
@@ -757,7 +757,7 @@ static void esp_do_nodma(ESPState *s)
 
 case CMD_SELATNS:
 /* Copy one byte from FIFO into cmdfifo */
-len = esp_fifo_pop_buf(>fifo, buf, 1);
+len = esp_fifo_pop_buf(s, buf, 1);
 len = MIN(fifo8_num_free(>cmdfifo), len);
 fifo8_push_all(>cmdfifo, buf, len);
 
@@ -774,7 +774,7 @@ static void esp_do_nodma(ESPState *s)
 
 case CMD_TI:
 /* Copy FIFO into cmdfifo */
-len = esp_fifo_pop_buf(>fifo, buf, fifo8_num_used(>fifo));
+len = esp_fifo_pop_buf(s, buf, fifo8_num_used(>fifo));
 len = MIN(fifo8_num_free(>cmdfifo), len);
 fifo8_push_all(>cmdfifo, buf, len);
 
@@ -792,7 +792,7 @@ static void esp_do_nodma(ESPState *s)
 switch (s->rregs[ESP_CMD]) {
 case CMD_TI:
 /* Copy FIFO into cmdfifo */
-len = esp_fifo_pop_buf(>fifo, buf, fifo8_num_used(>fifo));
+len = esp_fifo_pop_buf(s, buf, fifo8_num_used(>fifo));
 len = MIN(fifo8_num_free(>cmdfifo), len);
 fifo8_push_all(>cmdfifo, buf, len);
 
@@ -821,7 +821,7 @@ static void esp_do_nodma(ESPState *s)
 case CMD_SEL | CMD_DMA:
 case CMD_SELATN | CMD_DMA:
 /* Copy FIFO into cmdfifo */
-len = esp_fifo_pop_buf(>fifo, buf, fifo8_num_used(>fifo));
+len = esp_fifo_pop_buf(s, buf, fifo8_num_used(>fifo));
 len = MIN(fifo8_num_free(>cmdfifo), len);
 fifo8_push_all(>cmdfifo, buf, len);
 
@@ -836,7 +836,7 @@ static void esp_do_nodma(ESPState *s)
 case CMD_SEL:
 case CMD_SELATN:
 /* FIFO already contain entire CDB: copy to cmdfifo and execute */
-len = esp_fifo_pop_buf(>fifo, buf, fifo8_num_used(>fifo));
+len = esp_fifo_pop_buf(s, buf, fifo8_num_used(>fifo));
 len = MIN(fifo8_num_free(>cmdfifo), len);
 fifo8_push_all(>cmdfifo, buf, len);
 
-- 
2.39.2




[PATCH v3 07/17] esp.c: use esp_fifo_push() instead of fifo8_push()

2024-03-24 Thread Mark Cave-Ayland
There are still a few places that use fifo8_push() instead of esp_fifo_push() in
order to push a value into the FIFO. Update those places to use esp_fifo_push()
instead.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/scsi/esp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index d474268438..8d2d36d56c 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -858,7 +858,7 @@ static void esp_do_nodma(ESPState *s)
 return;
 }
 if (fifo8_is_empty(>fifo)) {
-fifo8_push(>fifo, s->async_buf[0]);
+esp_fifo_push(s, s->async_buf[0]);
 s->async_buf++;
 s->async_len--;
 s->ti_size--;
@@ -881,7 +881,7 @@ static void esp_do_nodma(ESPState *s)
 case STAT_ST:
 switch (s->rregs[ESP_CMD]) {
 case CMD_ICCS:
-fifo8_push(>fifo, s->status);
+esp_fifo_push(s, s->status);
 esp_set_phase(s, STAT_MI);
 
 /* Process any message in phase data */
@@ -893,7 +893,7 @@ static void esp_do_nodma(ESPState *s)
 case STAT_MI:
 switch (s->rregs[ESP_CMD]) {
 case CMD_ICCS:
-fifo8_push(>fifo, 0);
+esp_fifo_push(s, 0);
 
 /* Raise end of command interrupt */
 s->rregs[ESP_RINTR] |= INTR_FC;
-- 
2.39.2




[PATCH v3 06/17] esp.c: change esp_fifo_pop() to take ESPState

2024-03-24 Thread Mark Cave-Ayland
Now that all users of esp_fifo_pop() operate on the main FIFO there is no need
to pass the FIFO explicitly.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/scsi/esp.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 7e3338815b..d474268438 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -116,13 +116,13 @@ static void esp_fifo_push(ESPState *s, uint8_t val)
 fifo8_push(>fifo, val);
 }
 
-static uint8_t esp_fifo_pop(Fifo8 *fifo)
+static uint8_t esp_fifo_pop(ESPState *s)
 {
-if (fifo8_is_empty(fifo)) {
+if (fifo8_is_empty(>fifo)) {
 return 0;
 }
 
-return fifo8_pop(fifo);
+return fifo8_pop(>fifo);
 }
 
 static uint32_t esp_fifo8_pop_buf(Fifo8 *fifo, uint8_t *dest, int maxlen)
@@ -217,7 +217,7 @@ static uint8_t esp_pdma_read(ESPState *s)
 {
 uint8_t val;
 
-val = esp_fifo_pop(>fifo);
+val = esp_fifo_pop(s);
 return val;
 }
 
@@ -1184,7 +1184,7 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
 
 switch (saddr) {
 case ESP_FIFO:
-s->rregs[ESP_FIFO] = esp_fifo_pop(>fifo);
+s->rregs[ESP_FIFO] = esp_fifo_pop(s);
 val = s->rregs[ESP_FIFO];
 break;
 case ESP_RINTR:
-- 
2.39.2




[PATCH v3 11/17] esp.c: rework esp_cdb_length() into esp_cdb_ready()

2024-03-24 Thread Mark Cave-Ayland
The esp_cdb_length() function is only used as part of a calculation to determine
whether the cmdfifo contains an entire SCSI CDB. Rework esp_cdb_length() into a
new esp_cdb_ready() function which both enables us to handle the case where
scsi_cdb_length() returns -1, plus simplify the logic for its callers.

Suggested-by: Paolo Bonzini 
Signed-off-by: Mark Cave-Ayland 
---
 hw/scsi/esp.c | 30 ++
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index f3aa5364cf..f47abc36d6 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -425,20 +425,20 @@ static void write_response(ESPState *s)
 }
 }
 
-static int esp_cdb_length(ESPState *s)
+static bool esp_cdb_ready(ESPState *s)
 {
+int len = fifo8_num_used(>cmdfifo) - s->cmdfifo_cdb_offset;
 const uint8_t *pbuf;
-int cmdlen, len;
+int cdblen;
 
-cmdlen = fifo8_num_used(>cmdfifo);
-if (cmdlen < s->cmdfifo_cdb_offset) {
-return 0;
+if (len <= 0) {
+return false;
 }
 
-pbuf = fifo8_peek_buf(>cmdfifo, cmdlen, NULL);
-len = scsi_cdb_length((uint8_t *)[s->cmdfifo_cdb_offset]);
+pbuf = fifo8_peek_buf(>cmdfifo, len, NULL);
+cdblen = scsi_cdb_length((uint8_t *)[s->cmdfifo_cdb_offset]);
 
-return len;
+return cdblen < 0 ? false : (len >= cdblen);
 }
 
 static void esp_dma_ti_check(ESPState *s)
@@ -806,10 +806,9 @@ static void esp_do_nodma(ESPState *s)
 trace_esp_handle_ti_cmd(cmdlen);
 
 /* CDB may be transferred in one or more TI commands */
-if (esp_cdb_length(s) && esp_cdb_length(s) ==
-fifo8_num_used(>cmdfifo) - s->cmdfifo_cdb_offset) {
-/* Command has been received */
-do_cmd(s);
+if (esp_cdb_ready(s)) {
+/* Command has been received */
+do_cmd(s);
 } else {
 /*
  * If data was transferred from the FIFO then raise bus
@@ -832,10 +831,9 @@ static void esp_do_nodma(ESPState *s)
 fifo8_push_all(>cmdfifo, buf, len);
 
 /* Handle when DMA transfer is terminated by non-DMA FIFO write */
-if (esp_cdb_length(s) && esp_cdb_length(s) ==
-fifo8_num_used(>cmdfifo) - s->cmdfifo_cdb_offset) {
-/* Command has been received */
-do_cmd(s);
+if (esp_cdb_ready(s)) {
+/* Command has been received */
+do_cmd(s);
 }
 break;
 
-- 
2.39.2




[PATCH v3 15/17] esp.c: update esp_fifo_{push, pop}() to call esp_update_drq()

2024-03-24 Thread Mark Cave-Ayland
This ensures that the DRQ line is always set correctly when reading/writing
single bytes to/from the FIFO.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/scsi/esp.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 6fd1a12f23..4895181ec1 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -170,10 +170,11 @@ static void esp_fifo_push(ESPState *s, uint8_t val)
 {
 if (fifo8_num_used(>fifo) == s->fifo.capacity) {
 trace_esp_error_fifo_overrun();
-return;
+} else {
+fifo8_push(>fifo, val);
 }
 
-fifo8_push(>fifo, val);
+esp_update_drq(s);
 }
 
 static void esp_fifo_push_buf(ESPState *s, uint8_t *buf, int len)
@@ -184,11 +185,16 @@ static void esp_fifo_push_buf(ESPState *s, uint8_t *buf, 
int len)
 
 static uint8_t esp_fifo_pop(ESPState *s)
 {
+uint8_t val;
+
 if (fifo8_is_empty(>fifo)) {
-return 0;
+val = 0;
+} else {
+val = fifo8_pop(>fifo);
 }
 
-return fifo8_pop(>fifo);
+esp_update_drq(s);
+return val;
 }
 
 static uint32_t esp_fifo8_pop_buf(Fifo8 *fifo, uint8_t *dest, int maxlen)
-- 
2.39.2




[PATCH v3 16/17] esp.c: ensure esp_pdma_write() always calls esp_fifo_push()

2024-03-24 Thread Mark Cave-Ayland
This ensures that esp_update_drq() is called via esp_fifo_push() whenever the
host uses PDMA to transfer data to a SCSI device.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/scsi/esp.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 4895181ec1..04dfd90090 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -282,14 +282,12 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
 {
 uint32_t dmalen = esp_get_tc(s);
 
-if (dmalen == 0) {
-return;
-}
-
 esp_fifo_push(s, val);
 
-dmalen--;
-esp_set_tc(s, dmalen);
+if (dmalen && s->drq_state) {
+dmalen--;
+esp_set_tc(s, dmalen);
+}
 }
 
 static int esp_select(ESPState *s)
-- 
2.39.2




[PATCH v3 14/17] esp.c: introduce esp_update_drq() and update esp_fifo_{push, pop}_buf() to use it

2024-03-24 Thread Mark Cave-Ayland
This new function sets the DRQ line correctly according to the current transfer
mode, direction and FIFO contents. Update esp_fifo_push_buf() and 
esp_fifo_pop_buf()
to use it so that DRQ is always set correctly when reading/writing multiple 
bytes
to/from the FIFO.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/scsi/esp.c | 48 +++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 9e35c00927..6fd1a12f23 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -124,6 +124,48 @@ void esp_request_cancelled(SCSIRequest *req)
 }
 }
 
+static void esp_update_drq(ESPState *s)
+{
+bool to_device;
+
+switch (esp_get_phase(s)) {
+case STAT_MO:
+case STAT_CD:
+case STAT_DO:
+to_device = true;
+break;
+
+case STAT_DI:
+case STAT_ST:
+case STAT_MI:
+to_device = false;
+break;
+
+default:
+return;
+}
+
+if (s->dma) {
+/* DMA request so update DRQ according to transfer direction */
+if (to_device) {
+if (fifo8_num_free(>fifo) < 2) {
+esp_lower_drq(s);
+} else {
+esp_raise_drq(s);
+}
+} else {
+if (fifo8_num_used(>fifo) < 2) {
+esp_lower_drq(s);
+} else {
+esp_raise_drq(s);
+}
+}
+} else {
+/* Not a DMA request */
+esp_lower_drq(s);
+}
+}
+
 static void esp_fifo_push(ESPState *s, uint8_t val)
 {
 if (fifo8_num_used(>fifo) == s->fifo.capacity) {
@@ -137,6 +179,7 @@ static void esp_fifo_push(ESPState *s, uint8_t val)
 static void esp_fifo_push_buf(ESPState *s, uint8_t *buf, int len)
 {
 fifo8_push_all(>fifo, buf, len);
+esp_update_drq(s);
 }
 
 static uint8_t esp_fifo_pop(ESPState *s)
@@ -180,7 +223,10 @@ static uint32_t esp_fifo8_pop_buf(Fifo8 *fifo, uint8_t 
*dest, int maxlen)
 
 static uint32_t esp_fifo_pop_buf(ESPState *s, uint8_t *dest, int maxlen)
 {
-return esp_fifo8_pop_buf(>fifo, dest, maxlen);
+uint32_t len = esp_fifo8_pop_buf(>fifo, dest, maxlen);
+
+esp_update_drq(s);
+return len;
 }
 
 static uint32_t esp_get_tc(ESPState *s)
-- 
2.39.2




[PATCH v3 04/17] esp.c: replace cmdfifo use of esp_fifo_pop() in do_message_phase()

2024-03-24 Thread Mark Cave-Ayland
Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/scsi/esp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 9386704a58..5b169b3720 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -315,7 +315,8 @@ static void do_command_phase(ESPState *s)
 static void do_message_phase(ESPState *s)
 {
 if (s->cmdfifo_cdb_offset) {
-uint8_t message = esp_fifo_pop(>cmdfifo);
+uint8_t message = fifo8_is_empty(>cmdfifo) ? 0 :
+  fifo8_pop(>cmdfifo);
 
 trace_esp_do_identify(message);
 s->lun = message & 7;
-- 
2.39.2




[PATCH v3 09/17] esp.c: introduce esp_fifo_push_buf() function for pushing to the FIFO

2024-03-24 Thread Mark Cave-Ayland
Instead of pushing data into the FIFO directly with fifo8_push_all(), add a new
esp_fifo_push_buf() function and use it accordingly.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/scsi/esp.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 83b621ee0f..1aac8f5564 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -116,6 +116,11 @@ static void esp_fifo_push(ESPState *s, uint8_t val)
 fifo8_push(>fifo, val);
 }
 
+static void esp_fifo_push_buf(ESPState *s, uint8_t *buf, int len)
+{
+fifo8_push_all(>fifo, buf, len);
+}
+
 static uint8_t esp_fifo_pop(ESPState *s)
 {
 if (fifo8_is_empty(>fifo)) {
@@ -601,7 +606,7 @@ static void esp_do_dma(ESPState *s)
 } else {
 /* Copy device data to FIFO */
 len = MIN(len, fifo8_num_free(>fifo));
-fifo8_push_all(>fifo, s->async_buf, len);
+esp_fifo_push_buf(s, s->async_buf, len);
 esp_raise_drq(s);
 }
 
@@ -650,7 +655,7 @@ static void esp_do_dma(ESPState *s)
 if (s->dma_memory_write) {
 s->dma_memory_write(s->dma_opaque, buf, len);
 } else {
-fifo8_push_all(>fifo, buf, len);
+esp_fifo_push_buf(s, buf, len);
 }
 
 esp_set_tc(s, esp_get_tc(s) - len);
@@ -685,7 +690,7 @@ static void esp_do_dma(ESPState *s)
 if (s->dma_memory_write) {
 s->dma_memory_write(s->dma_opaque, buf, len);
 } else {
-fifo8_push_all(>fifo, buf, len);
+esp_fifo_push_buf(s, buf, len);
 }
 
 esp_set_tc(s, esp_get_tc(s) - len);
-- 
2.39.2




[PATCH v3 17/17] esp.c: remove explicit setting of DRQ within ESP state machine

2024-03-24 Thread Mark Cave-Ayland
Now the esp_update_drq() is called for all reads/writes to the FIFO, there is
no need to manually raise and lower the DRQ signal.

Signed-off-by: Mark Cave-Ayland 
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/611
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1831
---
 hw/scsi/esp.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 04dfd90090..5d9b52632e 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -506,7 +506,6 @@ static void esp_dma_ti_check(ESPState *s)
 if (esp_get_tc(s) == 0 && fifo8_num_used(>fifo) < 2) {
 s->rregs[ESP_RINTR] |= INTR_BS;
 esp_raise_irq(s);
-esp_lower_drq(s);
 }
 }
 
@@ -526,7 +525,6 @@ static void esp_do_dma(ESPState *s)
 } else {
 len = esp_fifo_pop_buf(s, buf, fifo8_num_used(>fifo));
 len = MIN(fifo8_num_free(>cmdfifo), len);
-esp_raise_drq(s);
 }
 
 fifo8_push_all(>cmdfifo, buf, len);
@@ -583,7 +581,6 @@ static void esp_do_dma(ESPState *s)
 len = esp_fifo_pop_buf(s, buf, fifo8_num_used(>fifo));
 len = MIN(fifo8_num_free(>cmdfifo), len);
 fifo8_push_all(>cmdfifo, buf, len);
-esp_raise_drq(s);
 }
 trace_esp_handle_ti_cmd(cmdlen);
 s->ti_size = 0;
@@ -615,7 +612,6 @@ static void esp_do_dma(ESPState *s)
 len = MIN(s->async_len, ESP_FIFO_SZ);
 len = MIN(len, fifo8_num_used(>fifo));
 len = esp_fifo_pop_buf(s, s->async_buf, len);
-esp_raise_drq(s);
 }
 
 s->async_buf += len;
@@ -667,7 +663,6 @@ static void esp_do_dma(ESPState *s)
 /* Copy device data to FIFO */
 len = MIN(len, fifo8_num_free(>fifo));
 esp_fifo_push_buf(s, s->async_buf, len);
-esp_raise_drq(s);
 }
 
 s->async_buf += len;
@@ -733,7 +728,6 @@ static void esp_do_dma(ESPState *s)
 if (fifo8_num_used(>fifo) < 2) {
 s->rregs[ESP_RINTR] |= INTR_BS;
 esp_raise_irq(s);
-esp_lower_drq(s);
 }
 break;
 }
@@ -1021,9 +1015,6 @@ void esp_command_complete(SCSIRequest *req, size_t resid)
 s->rregs[ESP_RINTR] |= INTR_BS;
 esp_raise_irq(s);
 
-/* Ensure DRQ is set correctly for TC underflow or normal completion */
-esp_dma_ti_check(s);
-
 if (s->current_req) {
 scsi_req_unref(s->current_req);
 s->current_req = NULL;
-- 
2.39.2




[PATCH v3 03/17] esp.c: replace esp_fifo_pop_buf() with esp_fifo8_pop_buf() in do_message_phase()

2024-03-24 Thread Mark Cave-Ayland
The aim is to restrict the esp_fifo_*() functions so that they only operate on
the hardware FIFO. When reading from cmdfifo in do_message_phase() use the
underlying esp_fifo8_pop_buf() function directly.

Signed-off-by: Mark Cave-Ayland 
---
 hw/scsi/esp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index ff51145da7..9386704a58 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -325,7 +325,7 @@ static void do_message_phase(ESPState *s)
 /* Ignore extended messages for now */
 if (s->cmdfifo_cdb_offset) {
 int len = MIN(s->cmdfifo_cdb_offset, fifo8_num_used(>cmdfifo));
-esp_fifo_pop_buf(>cmdfifo, NULL, len);
+esp_fifo8_pop_buf(>cmdfifo, NULL, len);
 s->cmdfifo_cdb_offset = 0;
 }
 }
-- 
2.39.2




[PATCH v3 12/17] esp.c: prevent cmdfifo overflow in esp_cdb_ready()

2024-03-24 Thread Mark Cave-Ayland
During normal use the cmdfifo will never wrap internally and cmdfifo_cdb_offset
will always indicate the start of the SCSI CDB. However it is possible that a
malicious guest could issue an invalid ESP command sequence such that cmdfifo
wraps internally and cmdfifo_cdb_offset could point beyond the end of the FIFO
data buffer.

Add an extra check to fifo8_peek_buf() to ensure that if the cmdfifo has wrapped
internally then esp_cdb_ready() will exit rather than allow scsi_cdb_length() to
access data outside the cmdfifo data buffer.

Reported-by: Chuhong Yuan 
Signed-off-by: Mark Cave-Ayland 
---
 hw/scsi/esp.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index f47abc36d6..d8db33b921 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -429,13 +429,23 @@ static bool esp_cdb_ready(ESPState *s)
 {
 int len = fifo8_num_used(>cmdfifo) - s->cmdfifo_cdb_offset;
 const uint8_t *pbuf;
+uint32_t n;
 int cdblen;
 
 if (len <= 0) {
 return false;
 }
 
-pbuf = fifo8_peek_buf(>cmdfifo, len, NULL);
+pbuf = fifo8_peek_buf(>cmdfifo, len, );
+if (n < len) {
+/*
+ * In normal use the cmdfifo should never wrap, but include this check
+ * to prevent a malicious guest from reading past the end of the
+ * cmdfifo data buffer below
+ */
+return false;
+}
+
 cdblen = scsi_cdb_length((uint8_t *)[s->cmdfifo_cdb_offset]);
 
 return cdblen < 0 ? false : (len >= cdblen);
-- 
2.39.2




[PATCH v3 13/17] esp.c: move esp_set_phase() and esp_get_phase() towards the beginning of the file

2024-03-24 Thread Mark Cave-Ayland
This allows these functions to be used earlier in the file without needing a
separate forward declaration.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/scsi/esp.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index d8db33b921..9e35c00927 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -79,6 +79,24 @@ static void esp_lower_drq(ESPState *s)
 }
 }
 
+static const char *esp_phase_names[8] = {
+"DATA OUT", "DATA IN", "COMMAND", "STATUS",
+"(reserved)", "(reserved)", "MESSAGE OUT", "MESSAGE IN"
+};
+
+static void esp_set_phase(ESPState *s, uint8_t phase)
+{
+s->rregs[ESP_RSTAT] &= ~7;
+s->rregs[ESP_RSTAT] |= phase;
+
+trace_esp_set_phase(esp_phase_names[phase]);
+}
+
+static uint8_t esp_get_phase(ESPState *s)
+{
+return s->rregs[ESP_RSTAT] & 7;
+}
+
 void esp_dma_enable(ESPState *s, int irq, int level)
 {
 if (level) {
@@ -200,24 +218,6 @@ static uint32_t esp_get_stc(ESPState *s)
 return dmalen;
 }
 
-static const char *esp_phase_names[8] = {
-"DATA OUT", "DATA IN", "COMMAND", "STATUS",
-"(reserved)", "(reserved)", "MESSAGE OUT", "MESSAGE IN"
-};
-
-static void esp_set_phase(ESPState *s, uint8_t phase)
-{
-s->rregs[ESP_RSTAT] &= ~7;
-s->rregs[ESP_RSTAT] |= phase;
-
-trace_esp_set_phase(esp_phase_names[phase]);
-}
-
-static uint8_t esp_get_phase(ESPState *s)
-{
-return s->rregs[ESP_RSTAT] & 7;
-}
-
 static uint8_t esp_pdma_read(ESPState *s)
 {
 uint8_t val;
-- 
2.39.2




[PATCH v3 00/17] [for-9.0] esp: avoid explicit setting of DRQ within ESP state machine

2024-03-24 Thread Mark Cave-Ayland
[MCA: Since v1 I've received a few reports of FIFO assert()s being triggered 
and a
cmdfifo buffer overflow discovered by fuzzing the updated ESP code. The 
updating of
all FIFO push/pop operations to use the esp_fifo_*() functions in this series
provides protection against this, and in conjunction with new patches 9-11 is
enough to prevent all qtest reproducers that I have been sent.

For these reasons I would recommend that this series be applied for 9.0. Many 
thanks
to Chuhong Yuan  for reporting the issues and providing 
qtest
reproducers.]

The ESP device has a DRQ (DMA request) signal that is used to handle flow 
control
during DMA transfers. At the moment the DRQ signal is explicitly raised and
lowered at various points in the ESP state machine as required, rather than
implementing the logic described in the datasheet:

"DREQ will remain true as long as either the FIFO contains at least one word (or
one byte if 8-bit mode) to send to memory during DMA read, or has room for one 
more
word (or byte if 8-bit mode) in the FIFO during DMA write."

This series updates the ESP device to use the same logic as described above 
which
also fixes a couple of outstanding GitLab issues related to recovery handling
during FIFO overflow on 68k Macs using PDMA.

Patches 1-4 update existing users of esp_fifo_pop_buf() and esp_fifo_pop() with
the internal cmdfifo to use the underlying Fifo8 device directly. The aim is
to ensure that all the esp_fifo_*() functions only operate on the ESP's hardware
FIFO.

Patches 5-6 update esp_fifo_push() and esp_fifo_pop() to take ESPState directly
as a parameter to prevent any usage that doesn't reference the ESP hardware
FIFO.

Patch 7 ensures that any usage of fifo8_push() for the ESP hardware FIFO is
updated to use esp_fifo_push() instead.

Patch 8 updates esp_fifo_pop_buf() to take ESPState directly as a parameter
to prevent any usage that doesn't reference the ESP hardware FIFO.

Patch 9 introduces the esp_fifo_push_buf() function for pushing multiple bytes
to the ESP hardware FIFO, and updates callers to use it accordingly.

Patches 10-12 incorporate additional protection to prevent FIFO assert()s and a
cmdfifo buffer overflow discovered via fuzzing.

Patch 13 is just code movement which avoids the use of a forward declaration 
whilst
also making it easier to locate the mapping between ESP SCSI phases and their
names.

Patches 14 introduce a new esp_update_drq() function that implements the above
DRQ logic which is called by both esp_fifo_{push,pop}_buf().

Patch 15 updates esp_fifo_push() and esp_fifo_pop() to use the new 
esp_update_drq()
function. At this point all reads/writes to the ESP FIFO use the esp_fifo_*()
functions and will set DRQ correctly.

Patch 16 is a small update to the logic in esp_pdma_write() to ensure that
esp_fifo_push() is always called for PDMA writes to the FIFO, thereby ensuring
that esp_update_drq() remains correct even in the case of FIFO overflow.

Finally patch 17 removes all manual calls to esp_raise_drq() and esp_lower_drq()
since the DRQ signal is now updated correctly upon each FIFO read/write access.

Signed-off-by: Mark Cave-Ayland 

v3:
- Rebase onto master
- Add patch 1 to move the internals of esp_fifo_pop_buf() to a new
  esp_fifo8_pop_buf() function. This allows the FIFO wrap logic to still be
  used for managing cmdfifo
- Rework esp_cdb_length() into esp_cdb_ready() as suggested by Paolo in patch
  11
- Update the logic in patch 12 to use the new esp_cdb_ready() function

v2:
- Rebase onto master
- Add patches 9-12 to handle FIFO assert()s and cmdfifo overflow as reported by
  Chuhong Yuan 


Mark Cave-Ayland (17):
  esp.c: move esp_fifo_pop_buf() internals to new esp_fifo8_pop_buf()
function
  esp.c: replace esp_fifo_pop_buf() with esp_fifo8_pop_buf() in
do_command_phase()
  esp.c: replace esp_fifo_pop_buf() with esp_fifo8_pop_buf() in
do_message_phase()
  esp.c: replace cmdfifo use of esp_fifo_pop() in do_message_phase()
  esp.c: change esp_fifo_push() to take ESPState
  esp.c: change esp_fifo_pop() to take ESPState
  esp.c: use esp_fifo_push() instead of fifo8_push()
  esp.c: change esp_fifo_pop_buf() to take ESPState
  esp.c: introduce esp_fifo_push_buf() function for pushing to the FIFO
  esp.c: don't assert() if FIFO empty when executing non-DMA SELATNS
  esp.c: rework esp_cdb_length() into esp_cdb_ready()
  esp.c: prevent cmdfifo overflow in esp_cdb_ready()
  esp.c: move esp_set_phase() and esp_get_phase() towards the beginning
of the file
  esp.c: introduce esp_update_drq() and update esp_fifo_{push,pop}_buf()
to use it
  esp.c: update esp_fifo_{push,pop}() to call esp_update_drq()
  esp.c: ensure esp_pdma_write() always calls esp_fifo_push()
  esp.c: remove explicit setting of DRQ within ESP state machine

 hw/scsi/esp.c | 223 --
 1 file changed, 142 insertions(+), 81 deletions(-)

-- 
2.39.2




[PATCH v3 01/17] esp.c: move esp_fifo_pop_buf() internals to new esp_fifo8_pop_buf() function

2024-03-24 Thread Mark Cave-Ayland
Update esp_fifo_pop_buf() to be a simple wrapper onto the new 
esp_fifo8_pop_buf()
function.

Signed-off-by: Mark Cave-Ayland 
---
 hw/scsi/esp.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 590ff99744..1b7b118a0b 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -125,7 +125,7 @@ static uint8_t esp_fifo_pop(Fifo8 *fifo)
 return fifo8_pop(fifo);
 }
 
-static uint32_t esp_fifo_pop_buf(Fifo8 *fifo, uint8_t *dest, int maxlen)
+static uint32_t esp_fifo8_pop_buf(Fifo8 *fifo, uint8_t *dest, int maxlen)
 {
 const uint8_t *buf;
 uint32_t n, n2;
@@ -155,6 +155,11 @@ static uint32_t esp_fifo_pop_buf(Fifo8 *fifo, uint8_t 
*dest, int maxlen)
 return n;
 }
 
+static uint32_t esp_fifo_pop_buf(Fifo8 *fifo, uint8_t *dest, int maxlen)
+{
+return esp_fifo8_pop_buf(fifo, dest, maxlen);
+}
+
 static uint32_t esp_get_tc(ESPState *s)
 {
 uint32_t dmalen;
-- 
2.39.2




[PATCH v3 05/17] esp.c: change esp_fifo_push() to take ESPState

2024-03-24 Thread Mark Cave-Ayland
Now that all users of esp_fifo_push() operate on the main FIFO there is no need
to pass the FIFO explicitly.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/scsi/esp.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 5b169b3720..7e3338815b 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -106,14 +106,14 @@ void esp_request_cancelled(SCSIRequest *req)
 }
 }
 
-static void esp_fifo_push(Fifo8 *fifo, uint8_t val)
+static void esp_fifo_push(ESPState *s, uint8_t val)
 {
-if (fifo8_num_used(fifo) == fifo->capacity) {
+if (fifo8_num_used(>fifo) == s->fifo.capacity) {
 trace_esp_error_fifo_overrun();
 return;
 }
 
-fifo8_push(fifo, val);
+fifo8_push(>fifo, val);
 }
 
 static uint8_t esp_fifo_pop(Fifo8 *fifo)
@@ -229,7 +229,7 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
 return;
 }
 
-esp_fifo_push(>fifo, val);
+esp_fifo_push(s, val);
 
 dmalen--;
 esp_set_tc(s, dmalen);
@@ -1240,7 +1240,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t 
val)
 break;
 case ESP_FIFO:
 if (!fifo8_is_full(>fifo)) {
-esp_fifo_push(>fifo, val);
+esp_fifo_push(s, val);
 }
 esp_do_nodma(s);
 break;
-- 
2.39.2




Re: [PATCH 2/3] target/hppa: mask offset bits in gva

2024-03-24 Thread Sven Schnelle
Hi Richard,

Richard Henderson  writes:

> In particular Figure 2-14 for "data translation disabled" may be
> instructive.  Suppose the cpu does not implement all of the physical
> address lines (true for all extant pa-risc cpus; qemu implements 40
> bits to match pa-8500 iirc).  Suppose when reporting a trap with
> translation disabled, it is a truncated physical address that is used
> as input to Figure 2-14.
>
> If that is so, then the fix might be in hppa_set_ior_and_isr.  Perhaps
>
> -env->cr[CR_ISR] &= 0x3fff;
> +env->cr[CR_ISR] &= 0x301f;
>
> Though my argument would suggest the mask should be 0xff for the
> 40-bit physical address, which is not what you see at all, so perhaps
> the thing is moot.  I am at a loss to explain why or how HP-UX gets a
> 7-bit hole in the ISR result.
>
> On the other hand, there are some not-well-documented shenanigans (aka
> implementation defined behaviour) between Figure H-8 and Figure H-11,
> where the 62-bit absolute address is expanded to a 64-bit logical
> physical address and then compacted to a 40-bit implementation
> physical address.
>
> We've already got hacks in place for this in hppa_abs_to_phys_pa2_w1,
> which just truncates everything down to 40 bits.  But that's probably
> not what the processor is really doing.
>
> Anyhow, will you please try the hppa_set_ior_and_isr change and see if
> that fixes your HP-UX problems?

The problem occurs with data address translation - it's working without,
which is not suprising because no exception can happen there. But as
soon as the kernel enables address translation it will hit a data tlb
miss exception because it can't find 0xfffb0500 in the page
tables. Trying to truncate the ISR in hppa_set_ior_and_isr() for the
data translation enabled case leads to this loop:

hppa_tlb_fill_excp env=0x55bf06e976e0 addr=0x3ffb0500 size=4 type=0 
mmu_idx=9
hppa_tlb_find_entry env=0x55bf06e976e0 ent=0x55bf06e97b30 valid=1 va_b=0x20 
va_e=0x2f pa=0x20
hppa_tlb_get_physical_address env=0x55bf06e976e0 ret=-1 prot=5 addr=0x26170c 
phys=0x26170c
hppa_tlb_flush_ent env=0x55bf06e976e0 ent=0x55bf06e97bf0 
va_b=0x301b va_e=0x301b0fff pa=0xfffb
hppa_tlb_itlba env=0x55bf06e976e0 ent=0x55bf06e97bf0 va_b=0x301b 
va_e=0x301b0fff pa=0xfffb
hppa_tlb_itlbp env=0x55bf06e976e0 ent=0x55bf06e97bf0 access_id=0 u=1 pl2=0 
pl1=0 type=1 b=0 d=0 t=0

So qemu is looking up 0x3ffb0500 in the TLB, can't find it,
raises an exception, HP-UX says: "ah nice, i have a translation for
you", but that doesn't match because we're only stripping the bits
in the ISR.

As i was a bit puzzled in the beginning what's going on, i dumped the
pagetables and wrote a small dump program:

68: val=000f47ff301f r2=110e0f01 r1=01e8ffe0 
phys=f47ff000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
680020: val=000f47fe301f r2=110e0f01 r1=01e8ffc0 
phys=f47fe000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
680060: val=000f47fc301f r2=110e0f01 r1=01e8ff80 
phys=f47fc000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5860: val=000fed3c301f r2=010e0001 r1=01fda780 
phys=fed3c000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d58e0: val=000fed38301f r2=010e0001 r1=01fda700 
phys=fed38000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d59a0: val=000fed32301f r2=010e0001 r1=01fda640 
phys=fed32000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d59e0: val=000fed30301f r2=110e0f01 r1=01fda600 
phys=fed3 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5a00: val=000fed2f301f r2=010e0001 r1=01fda5e0 
phys=fed2f000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5a20: val=000fed2e301f r2=010e0001 r1=01fda5c0 
phys=fed2e000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5a40: val=000fed2d301f r2=010e0001 r1=01fda5a0 
phys=fed2d000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5a60: val=000fed2c301f r2=010e0001 r1=01fda580 
phys=fed2c000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5a80: val=000fed2b301f r2=010e0001 r1=01fda560 
phys=fed2b000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5aa0: val=000fed2a301f r2=010e0001 r1=01fda540 
phys=fed2a000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5ac0: val=000fed29301f r2=010e0001 r1=01fda520 
phys=fed29000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5ae0: val=000fed28301f r2=010e0001 r1=01fda500 
phys=fed28000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5b00: val=000fed27301f r2=010e0001 r1=01fda4e0 
phys=fed27000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5b20: val=000fed26301f r2=010e0001 r1=01fda4c0 
phys=fed26000 4K aid=1 pl1=0, pl2=0 type=1 

Re: [PATCH 2/3] target/hppa: mask offset bits in gva

2024-03-24 Thread Richard Henderson

On 3/23/24 22:09, Sven Schnelle wrote:

The CPU seems to mask a few bits in the offset when running
under HP-UX. ISR/IOR register contents for an address in
the processor HPA (0xfffa) on my C8000 and J6750:

running on Linux: 3fff c000fffa0500
running on HP-UX: 301f c000fffa0500

I haven't found how this is switched (guess some diag in the
firmware), but linux + seabios seems to handle that as well,
so lets mask out the additional bits.

Signed-off-by: Sven Schnelle 
---
  target/hppa/cpu.h | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index a072d0bb63..9bc4d208fa 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -283,12 +283,13 @@ static inline int HPPA_BTLB_ENTRIES(CPUHPPAState *env)
  
  void hppa_translate_init(void);
  
+#define HPPA_GVA_OFFSET_MASK64 0x301f

  #define CPU_RESOLVING_TYPE TYPE_HPPA_CPU
  
  static inline uint64_t gva_offset_mask(target_ulong psw)

  {
  return (psw & PSW_W
-? MAKE_64BIT_MASK(0, 62)
+? HPPA_GVA_OFFSET_MASK64
  : MAKE_64BIT_MASK(0, 32));
  }
  


I'm not keen on this, because it contradicts the manual for forming an address.

Where I can imagine this sort of thing creeping in is the fact that you're getting a 
result from trap registers.  The cpu does not actually retain the original {space, offset} 
tuple that formed the GVA to fill the trap registers, but takes bits [62:32] and 
back-computes a space, and subtracts to re-form an offset.  See "Interruption Parameter 
Registers" in the pa20 manual.


In particular Figure 2-14 for "data translation disabled" may be instructive.  Suppose the 
cpu does not implement all of the physical address lines (true for all extant pa-risc 
cpus; qemu implements 40 bits to match pa-8500 iirc).  Suppose when reporting a trap with 
translation disabled, it is a truncated physical address that is used as input to Figure 2-14.


If that is so, then the fix might be in hppa_set_ior_and_isr.  Perhaps

-env->cr[CR_ISR] &= 0x3fff;
+env->cr[CR_ISR] &= 0x301f;

Though my argument would suggest the mask should be 0xff for the 40-bit physical address, 
which is not what you see at all, so perhaps the thing is moot.  I am at a loss to explain 
why or how HP-UX gets a 7-bit hole in the ISR result.


On the other hand, there are some not-well-documented shenanigans (aka implementation 
defined behaviour) between Figure H-8 and Figure H-11, where the 62-bit absolute address 
is expanded to a 64-bit logical physical address and then compacted to a 40-bit 
implementation physical address.


We've already got hacks in place for this in hppa_abs_to_phys_pa2_w1, which just truncates 
everything down to 40 bits.  But that's probably not what the processor is really doing.


Anyhow, will you please try the hppa_set_ior_and_isr change and see if that fixes your 
HP-UX problems?



r~



Re: [PULL 00/15] riscv-to-apply queue

2024-03-24 Thread Daniel Henrique Barboza




On 3/24/24 12:07, Michael Tokarev wrote:

22.03.2024 22:46, Daniel Henrique Barboza :



On 3/22/24 14:16, Michael Tokarev wrote:

22.03.2024 11:53, Alistair Francis :


RISC-V PR for 9.0

* Do not enable all named features by default
* A range of Vector fixes
* Update APLIC IDC after claiming iforce register
* Remove the dependency of Zvfbfmin to Zfbfmin
* Fix mode in riscv_tlb_fill
* Fix timebase-frequency when using KVM acceleration


Should something from there be picked up for stable (8.2 and probably 7.2)?


Ignore the "Do not enable all named features by default" since it's fixing 
something
that were added in 9.0.

The rest you can pick it up to 8.2 at least. Thanks,


Unfortunately this doesn't quite work, the following changes
fail to apply to 8.2:

929e521a47 target/riscv: always clear vstart for ldst_whole insns
b46631f122 target/riscv: remove 'over' brconds from vector trans
d57dfe4b37 trans_rvv.c.inc: remove redundant mark_vs_dirty() calls
bac802ada8 target/riscv: enable 'vstart_eq_zero' in the end of insns
385e575cd5 target/riscv/kvm: fix timebase-frequency when using KVM acceleration

I tried to back-port at least the first one but it turned out to be
another failure.  Didn't try looking at the rest.


This particular code (vector emulation) has been going through a lot of
changes in the last couple of releases, so I'm not surprised with the
difficulty with backporting these.



If these really should be in 8.2 (it's your guys to decide, not me),
I need help with back-porting these to 8.2 (and/or cherry-picking
additional patches from master).


The amount of work can be non-trivial for this backport, so I'd say we should
leave it aside for now. If someone has a good argument for this work then we
can re-evaluate.


Thanks,

Daniel



Thanks,

/mjt



Daniel Henrique Barboza (10):
   target/riscv: do not enable all named features by default
   target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX()
   trans_rvv.c.inc: set vstart = 0 in int scalar move insns
   target/riscv/vector_helper.c: fix 'vmvr_v' memcpy endianess
   target/riscv: always clear vstart in whole vec move insns
   target/riscv: always clear vstart for ldst_whole insns
   target/riscv/vector_helpers: do early exit when vstart >= vl
   target/riscv: remove 'over' brconds from vector trans
   trans_rvv.c.inc: remove redundant mark_vs_dirty() calls
   target/riscv/vector_helper.c: optimize loops in ldst helpers

Frank Chang (1):
   hw/intc: Update APLIC IDC after claiming iforce register

Irina Ryapolova (1):
   target/riscv: Fix mode in riscv_tlb_fill

Ivan Klokov (1):
   target/riscv: enable 'vstart_eq_zero' in the end of insns

Max Chou (1):
   target/riscv: rvv: Remove the dependency of Zvfbfmin to Zfbfmin

Yong-Xuan Wang (1):
   target/riscv/kvm: fix timebase-frequency when using KVM acceleration










Re: [PATCH 1/3] target/hppa: use gva_offset_mask() everywhere

2024-03-24 Thread Richard Henderson

On 3/23/24 22:09, Sven Schnelle wrote:

move it to cpu.h, so it can also be used in hppa_form_gva_psw()

Signed-off-by: Sven Schnelle
---
  target/hppa/cpu.h   | 10 --
  target/hppa/translate.c | 12 +++-
  2 files changed, 11 insertions(+), 11 deletions(-)


Reviewed-by: Richard Henderson 


r~



Re: [PATCH][RFC] target/hppa: Avoid nullification for uaddcmt instruction

2024-03-24 Thread Helge Deller

On 3/24/24 18:13, Richard Henderson wrote:

On 3/23/24 11:15, Helge Deller wrote:

The uaddcmt (UNIT ADD COMPLEMENT AND TRAP ON CONDITION) instruction
triggers a trap if the condition is true, and stores the result of the
addition in the target register otherwise.
It does not use the condition to nullify the following instruction, so
drop the calculated condition and do not install it as null_cond.


That's not what the manual says:

if (trapc == TC && cond_satisfied)
     conditional_trap;
else {
     GR[t] ← res;
     if (cond_satisfied) PSW[N] ← 1;
}


The above is from the 64-bit manual.
My mail was based on the info from the 32-bit manual, which says:
res ← GR[r1] + ∼GR[r2];
if (cond_satisfied)
conditional_trap;
else
GR[t] ← res

But basically it doesn't matter, since as you explain below,
if it traps, it won't return anyway and as such PSW[N] will
not be modified.


We have implemented this like so:

if (trapc == TC)
     conditional_trap(cond_satisfied);
GR[t] ← res;
if (cond_satisfied) PSW[N] ← 1;

because the conditional trap step does not return if it traps.


Yes.
Thanks for review anyway!

Helge


This patch is not tested and as such sent as RFC.
I just stumbled over the apparently wrong behaviour while debugging the
uaddcm instruction.


Under separate cover you said the condition might be computed incorrectly.  I 
think that is more likely the root cause of the wrong behaviour.


r~






Re: [PATCH 3/3] target/hppa: fix building gva for wide mode

2024-03-24 Thread Richard Henderson

On 3/23/24 22:09, Sven Schnelle wrote:

64 Bit hppa no longer has a fixed 32/32 bit split between space and
offset. Instead it uses 42 bits for the offset. The lower 10 bits of
the space are always zero, leaving 22 bits actually used. Simply or
the values together to build the gva.

Signed-off-by: Sven Schnelle 
---
  target/hppa/mem_helper.c | 13 +++--
  1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 84785b5a5c..6f895fced7 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -523,13 +523,16 @@ void HELPER(itlbp_pa11)(CPUHPPAState *env, target_ulong 
addr, target_ulong reg)
  }
  
  static void itlbt_pa20(CPUHPPAState *env, target_ulong r1,

-   target_ulong r2, vaddr va_b)
+   target_ulong r2, uint64_t spc, uint64_t off)
  {
  HPPATLBEntry *ent;
-vaddr va_e;
+vaddr va_b, va_e;
  uint64_t va_size;
  int mask_shift;
  
+va_b = off & gva_offset_mask(env->psw);

+va_b |= spc << 32;


Indeed, this ought to be using

va_b = hppa_form_gva_psw(env->psw, off, spc << 32);

With that,
Reviewed-by: Richard Henderson 


r~



Re: [PATCH][RFC] target/hppa: Avoid nullification for uaddcmt instruction

2024-03-24 Thread Richard Henderson

On 3/23/24 11:15, Helge Deller wrote:

The uaddcmt (UNIT ADD COMPLEMENT AND TRAP ON CONDITION) instruction
triggers a trap if the condition is true, and stores the result of the
addition in the target register otherwise.
It does not use the condition to nullify the following instruction, so
drop the calculated condition and do not install it as null_cond.


That's not what the manual says:

if (trapc == TC && cond_satisfied)
conditional_trap;
else {
GR[t] ← res;
if (cond_satisfied) PSW[N] ← 1;
}

We have implemented this like so:

if (trapc == TC)
conditional_trap(cond_satisfied);
GR[t] ← res;
if (cond_satisfied) PSW[N] ← 1;

because the conditional trap step does not return if it traps.



This patch is not tested and as such sent as RFC.
I just stumbled over the apparently wrong behaviour while debugging the
uaddcm instruction.


Under separate cover you said the condition might be computed incorrectly.  I think that 
is more likely the root cause of the wrong behaviour.



r~



[PATCH v2 6/6] tests/qtest: Add tests for the STM32L4x5 USART

2024-03-24 Thread Arnaud Minier
Test:
- read/write from/to the usart registers
- send/receive a character/string over the serial port

Signed-off-by: Arnaud Minier 
Signed-off-by: Inès Varhol 
---
 tests/qtest/meson.build|   3 +-
 tests/qtest/stm32l4x5_usart-test.c | 326 +
 2 files changed, 328 insertions(+), 1 deletion(-)
 create mode 100644 tests/qtest/stm32l4x5_usart-test.c

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 36c5c13a7b..e0d72ee91e 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -205,7 +205,8 @@ qtests_stm32l4x5 = \
   ['stm32l4x5_exti-test',
'stm32l4x5_syscfg-test',
'stm32l4x5_rcc-test',
-   'stm32l4x5_gpio-test']
+   'stm32l4x5_gpio-test',
+   'stm32l4x5_usart-test']
 
 qtests_arm = \
   (config_all_devices.has_key('CONFIG_MPS2') ? ['sse-timer-test'] : []) + \
diff --git a/tests/qtest/stm32l4x5_usart-test.c 
b/tests/qtest/stm32l4x5_usart-test.c
new file mode 100644
index 00..2d42f053f6
--- /dev/null
+++ b/tests/qtest/stm32l4x5_usart-test.c
@@ -0,0 +1,326 @@
+/*
+ * QTest testcase for STML4X5_USART
+ *
+ * Copyright (c) 2023 Arnaud Minier 
+ * Copyright (c) 2023 Inès Varhol 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "hw/misc/stm32l4x5_rcc_internals.h"
+#include "hw/registerfields.h"
+
+#define RCC_BASE_ADDR 0x40021000
+/* Use USART 1 ADDR, assume the others work the same */
+#define USART1_BASE_ADDR 0x40013800
+
+/* See stm32l4x5_usart for definitions */
+REG32(CR1, 0x00)
+FIELD(CR1, M1, 28, 1)
+FIELD(CR1, OVER8, 15, 1)
+FIELD(CR1, M0, 12, 1)
+FIELD(CR1, PCE, 10, 1)
+FIELD(CR1, TXEIE, 7, 1)
+FIELD(CR1, RXNEIE, 5, 1)
+FIELD(CR1, TE, 3, 1)
+FIELD(CR1, RE, 2, 1)
+FIELD(CR1, UE, 0, 1)
+REG32(CR2, 0x04)
+REG32(CR3, 0x08)
+FIELD(CR3, OVRDIS, 12, 1)
+REG32(BRR, 0x0C)
+REG32(GTPR, 0x10)
+REG32(RTOR, 0x14)
+REG32(RQR, 0x18)
+REG32(ISR, 0x1C)
+FIELD(ISR, TXE, 7, 1)
+FIELD(ISR, RXNE, 5, 1)
+FIELD(ISR, ORE, 3, 1)
+REG32(ICR, 0x20)
+REG32(RDR, 0x24)
+REG32(TDR, 0x28)
+
+#define NVIC_ISPR1 0XE000E204
+#define NVIC_ICPR1 0xE000E284
+#define USART1_IRQ 37
+
+static bool check_nvic_pending(QTestState *qts, unsigned int n)
+{
+/* No USART interrupts are less than 32 */
+assert(n > 32);
+n -= 32;
+return qtest_readl(qts, NVIC_ISPR1) & (1 << n);
+}
+
+static bool clear_nvic_pending(QTestState *qts, unsigned int n)
+{
+/* No USART interrupts are less than 32 */
+assert(n > 32);
+n -= 32;
+qtest_writel(qts, NVIC_ICPR1, (1 << n));
+return true;
+}
+
+/*
+ Tests should never need to sleep(), because while it might be plenty of time 
on a
+ fast development machine, it can cause intermittent failures due
+ to timeouts if the test is on some heavily-loaded slow CI runner.
+ */
+static bool usart_wait_for_flag(QTestState *qts, uint32_t event_addr, uint32_t 
flag)
+{
+/* Wait at most 10 minutes */
+for (int i = 0; i < 60; i++) {
+if ((qtest_readl(qts, event_addr) & flag)) {
+return true;
+}
+g_usleep(1000);
+}
+
+return false;
+}
+
+static void usart_receive_string(QTestState *qts, int sock_fd, const char *in,
+   char *out)
+{
+int i, in_len = strlen(in);
+
+g_assert_true(send(sock_fd, in, in_len, 0) == in_len);
+for (i = 0; i < in_len; i++) {
+g_assert_true(usart_wait_for_flag(qts,
+USART1_BASE_ADDR + A_ISR, R_ISR_RXNE_MASK));
+out[i] = qtest_readl(qts, USART1_BASE_ADDR + A_RDR);
+}
+out[i] = '\0';
+}
+
+static void usart_send_string(QTestState *qts, const char *in)
+{
+int i, in_len = strlen(in);
+
+for (i = 0; i < in_len; i++) {
+qtest_writel(qts, USART1_BASE_ADDR + A_TDR, in[i]);
+g_assert_true(usart_wait_for_flag(qts,
+USART1_BASE_ADDR + A_ISR, R_ISR_TXE_MASK));
+}
+}
+
+/* Init the RCC clocks to run at 80 MHz */
+static void init_clocks(QTestState *qts)
+{
+uint32_t value;
+
+/* MSIRANGE can be set only when MSI is OFF or READY */
+qtest_writel(qts, (RCC_BASE_ADDR + A_CR), R_CR_MSION_MASK);
+
+/* Clocking from MSI, in case MSI was not the default source */
+qtest_writel(qts, (RCC_BASE_ADDR + A_CFGR), 0);
+
+/*
+ * Update PLL and set MSI as the source clock.
+ * PLLM = 1 --> 000
+ * PLLN = 40 --> 40
+ * PPLLR = 2 --> 00
+ * PLLDIV = unused, PLLP = unused (SAI3), PLLQ = unused (48M1)
+ * SRC = MSI --> 01
+ */
+qtest_writel(qts, (RCC_BASE_ADDR + A_PLLCFGR), R_PLLCFGR_PLLREN_MASK |
+(40 << R_PLLCFGR_PLLN_SHIFT) |
+(0b01 << R_PLLCFGR_PLLSRC_SHIFT));
+
+/* PLL activation */
+
+value = qtest_readl(qts, (RCC_BASE_ADDR + A_CR));
+qtest_writel(qts, (RCC_BASE_ADDR + A_CR), value | R_CR_PLLON_MASK);
+
+/* RCC_CFGR is OK by defaut */
+qtest_writel(qts, 

[PATCH v2 4/6] hw/char/stm32l4x5_usart: Add options for serial parameters setting

2024-03-24 Thread Arnaud Minier
Add a function to change the settings of the
serial connection.

Signed-off-by: Arnaud Minier 
Signed-off-by: Inès Varhol 
---
 hw/char/stm32l4x5_usart.c | 98 +++
 hw/char/trace-events  |  1 +
 2 files changed, 99 insertions(+)

diff --git a/hw/char/stm32l4x5_usart.c b/hw/char/stm32l4x5_usart.c
index ec8c2f6e63..b4d11dd826 100644
--- a/hw/char/stm32l4x5_usart.c
+++ b/hw/char/stm32l4x5_usart.c
@@ -267,6 +267,92 @@ static void usart_cancel_transmit(Stm32l4x5UsartBaseState 
*s)
 }
 }
 
+static void stm32l4x5_update_params(Stm32l4x5UsartBaseState *s)
+{
+int speed, parity, data_bits, stop_bits;
+uint32_t value, usart_div;
+QEMUSerialSetParams ssp;
+
+/* Select the parity type */
+if (s->cr1 & R_CR1_PCE_MASK) {
+if (s->cr1 & R_CR1_PS_MASK) {
+parity = 'O';
+} else {
+parity = 'E';
+}
+} else {
+parity = 'N';
+}
+
+/* Select the number of stop bits */
+switch (FIELD_EX32(s->cr2, CR2, STOP)) {
+case 0:
+stop_bits = 1;
+break;
+case 2:
+stop_bits = 2;
+break;
+default:
+qemu_log_mask(LOG_UNIMP,
+"UNIMPLEMENTED: fractionnal stop bits; CR2[13:12] = %x",
+FIELD_EX32(s->cr2, CR2, STOP));
+return;
+}
+
+/* Select the length of the word */
+switch ((FIELD_EX32(s->cr1, CR1, M1) << 1) | FIELD_EX32(s->cr1, CR1, M0)) {
+case 0:
+data_bits = 8;
+break;
+case 1:
+data_bits = 9;
+break;
+case 2:
+data_bits = 7;
+break;
+default:
+qemu_log_mask(LOG_GUEST_ERROR,
+"UNDEFINED: invalid word length, CR1.M = 0b11");
+return;
+}
+
+/* Select the baud rate */
+value = FIELD_EX32(s->brr, BRR, BRR);
+if (value < 16) {
+qemu_log_mask(LOG_GUEST_ERROR,
+"UNDEFINED: BRR lesser than 16: %u", value);
+return;
+}
+
+if (FIELD_EX32(s->cr1, CR1, OVER8) == 0) {
+/*
+ * Oversampling by 16
+ * BRR = USARTDIV
+ */
+usart_div = value;
+} else {
+/*
+ * Oversampling by 8
+ * - BRR[2:0] = USARTDIV[3:0] shifted 1 bit to the right.
+ * - BRR[3] must be kept cleared.
+ * - BRR[15:4] = USARTDIV[15:4]
+ * - The frequency is multiplied by 2
+ */
+usart_div = ((value & 0xFFF0) | ((value & 0x0007) << 1)) / 2;
+}
+
+speed = clock_get_hz(s->clk) / usart_div;
+
+ssp.speed = speed;
+ssp.parity= parity;
+ssp.data_bits = data_bits;
+ssp.stop_bits = stop_bits;
+
+qemu_chr_fe_ioctl(>chr, CHR_IOCTL_SERIAL_SET_PARAMS, );
+
+trace_stm32l4x5_usart_update_params(speed, parity, data_bits, stop_bits);
+}
+
 static void stm32l4x5_usart_base_reset_hold(Object *obj)
 {
 Stm32l4x5UsartBaseState *s = STM32L4X5_USART_BASE(obj);
@@ -365,16 +451,19 @@ static void stm32l4x5_usart_base_write(void *opaque, 
hwaddr addr,
 switch (addr) {
 case A_CR1:
 s->cr1 = value;
+stm32l4x5_update_params(s);
 stm32l4x5_update_irq(s);
 return;
 case A_CR2:
 s->cr2 = value;
+stm32l4x5_update_params(s);
 return;
 case A_CR3:
 s->cr3 = value;
 return;
 case A_BRR:
 s->brr = value;
+stm32l4x5_update_params(s);
 return;
 case A_GTPR:
 s->gtpr = value;
@@ -443,10 +532,19 @@ static void stm32l4x5_usart_base_init(Object *obj)
 s->clk = qdev_init_clock_in(DEVICE(s), "clk", NULL, s, 0);
 }
 
+static int stm32l4x5_usart_base_post_load(void *opaque, int version_id)
+{
+Stm32l4x5UsartBaseState *s = (Stm32l4x5UsartBaseState *)opaque;
+
+stm32l4x5_update_params(s);
+return 0;
+}
+
 static const VMStateDescription vmstate_stm32l4x5_usart_base = {
 .name = TYPE_STM32L4X5_USART_BASE,
 .version_id = 1,
 .minimum_version_id = 1,
+.post_load = stm32l4x5_usart_base_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_UINT32(cr1, Stm32l4x5UsartBaseState),
 VMSTATE_UINT32(cr2, Stm32l4x5UsartBaseState),
diff --git a/hw/char/trace-events b/hw/char/trace-events
index f22f0ee2bc..8875758076 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -116,6 +116,7 @@ stm32l4x5_usart_irq_raised(uint32_t reg) "USART: IRQ 
raised: 0x%08"PRIx32
 stm32l4x5_usart_irq_lowered(void) "USART: IRQ lowered"
 stm32l4x5_usart_overrun_detected(uint8_t current, uint8_t received) "USART: 
Overrun detected, RDR='0x%x', received 0x%x"
 stm32l4x5_usart_receiver_not_enabled(uint8_t ue_bit, uint8_t re_bit) "USART: 
Receiver not enabled, UE=0x%x, RE=0x%x"
+stm32l4x5_usart_update_params(int speed, uint8_t parity, int data, int stop) 
"USART: speed: %d, parity: %c, data bits: %d, stop bits: %d"
 
 # xen_console.c
 xen_console_connect(unsigned int idx, unsigned int ring_ref, unsigned int 
port, unsigned int limit) "idx %u ring_ref %u port %u limit %u"
-- 

[PATCH v2 5/6] hw/arm: Add the USART to the stm32l4x5 SoC

2024-03-24 Thread Arnaud Minier
Add the USART to the SoC and connect it to the other implemented devices.

Signed-off-by: Arnaud Minier 
Signed-off-by: Inès Varhol 
---
 docs/system/arm/b-l475e-iot01a.rst |  2 +-
 hw/arm/Kconfig |  1 +
 hw/arm/stm32l4x5_soc.c | 82 +++---
 include/hw/arm/stm32l4x5_soc.h | 13 +
 4 files changed, 91 insertions(+), 7 deletions(-)

diff --git a/docs/system/arm/b-l475e-iot01a.rst 
b/docs/system/arm/b-l475e-iot01a.rst
index 0afef8e4f4..a76c9976c5 100644
--- a/docs/system/arm/b-l475e-iot01a.rst
+++ b/docs/system/arm/b-l475e-iot01a.rst
@@ -19,13 +19,13 @@ Currently B-L475E-IOT01A machine's only supports the 
following devices:
 - STM32L4x5 SYSCFG (System configuration controller)
 - STM32L4x5 RCC (Reset and clock control)
 - STM32L4x5 GPIOs (General-purpose I/Os)
+- STM32L4x5 USARTs, UARTs and LPUART (Serial ports)
 
 Missing devices
 """
 
 The B-L475E-IOT01A does *not* support the following devices:
 
-- Serial ports (UART)
 - Analog to Digital Converter (ADC)
 - SPI controller
 - Timer controller (TIMER)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 893a7bff66..098d043375 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -477,6 +477,7 @@ config STM32L4X5_SOC
 select STM32L4X5_SYSCFG
 select STM32L4X5_RCC
 select STM32L4X5_GPIO
+select STM32L4X5_USART
 
 config XLNX_ZYNQMP_ARM
 bool
diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
index 40e294f838..ae0868dcab 100644
--- a/hw/arm/stm32l4x5_soc.c
+++ b/hw/arm/stm32l4x5_soc.c
@@ -28,6 +28,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/or-irq.h"
 #include "hw/arm/stm32l4x5_soc.h"
+#include "hw/char/stm32l4x5_usart.h"
 #include "hw/gpio/stm32l4x5_gpio.h"
 #include "hw/qdev-clock.h"
 #include "hw/misc/unimp.h"
@@ -116,6 +117,22 @@ static const struct {
 { 0x48001C00, 0x000F, 0x, 0x },
 };
 
+static const hwaddr usart_addr[] = {
+0x40013800, /* "USART1", 0x400 */
+0x40004400, /* "USART2", 0x400 */
+0x40004800, /* "USART3", 0x400 */
+};
+static const hwaddr uart_addr[] = {
+0x40004C00, /* "UART4" , 0x400 */
+0x40005000  /* "UART5" , 0x400 */
+};
+
+#define LPUART_BASE_ADDRESS 0x40008000
+
+static const int usart_irq[] = { 37, 38, 39 };
+static const int uart_irq[] = { 52, 53 };
+#define LPUART_IRQ 70
+
 static void stm32l4x5_soc_initfn(Object *obj)
 {
 Stm32l4x5SocState *s = STM32L4X5_SOC(obj);
@@ -132,6 +149,18 @@ static void stm32l4x5_soc_initfn(Object *obj)
 g_autofree char *name = g_strdup_printf("gpio%c", 'a' + i);
 object_initialize_child(obj, name, >gpio[i], TYPE_STM32L4X5_GPIO);
 }
+
+for (int i = 0; i < STM_NUM_USARTS; i++) {
+object_initialize_child(obj, "usart[*]", >usart[i],
+TYPE_STM32L4X5_USART);
+}
+
+for (int i = 0; i < STM_NUM_UARTS; i++) {
+object_initialize_child(obj, "uart[*]", >uart[i],
+TYPE_STM32L4X5_UART);
+}
+object_initialize_child(obj, "lpuart1", >lpuart,
+TYPE_STM32L4X5_LPUART);
 }
 
 static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
@@ -279,6 +308,53 @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, 
Error **errp)
 sysbus_mmio_map(busdev, 0, RCC_BASE_ADDRESS);
 sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, RCC_IRQ));
 
+/* USART devices */
+for (int i = 0; i < STM_NUM_USARTS; i++) {
+dev = DEVICE(&(s->usart[i]));
+qdev_prop_set_chr(dev, "chardev", serial_hd(i));
+g_autofree char *name = g_strdup_printf("usart%d-out", i + 1);
+qdev_connect_clock_in(dev, "clk",
+qdev_get_clock_out(DEVICE(&(s->rcc)), name));
+busdev = SYS_BUS_DEVICE(dev);
+if (!sysbus_realize(busdev, errp)) {
+return;
+}
+sysbus_mmio_map(busdev, 0, usart_addr[i]);
+sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, usart_irq[i]));
+}
+
+/*
+ * TODO: Connect the USARTs, UARTs and LPUART to the EXTI once the EXTI
+ * can handle other gpio-in than the gpios. (e.g. Direct Lines for the 
usarts)
+ */
+
+/* UART devices */
+for (int i = 0; i < STM_NUM_UARTS; i++) {
+dev = DEVICE(&(s->uart[i]));
+qdev_prop_set_chr(dev, "chardev", serial_hd(STM_NUM_USARTS + i));
+g_autofree char *name = g_strdup_printf("uart%d-out", STM_NUM_USARTS + 
i + 1);
+qdev_connect_clock_in(dev, "clk",
+qdev_get_clock_out(DEVICE(&(s->rcc)), name));
+busdev = SYS_BUS_DEVICE(dev);
+if (!sysbus_realize(busdev, errp)) {
+return;
+}
+sysbus_mmio_map(busdev, 0, uart_addr[i]);
+sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, uart_irq[i]));
+}
+
+/* LPUART device*/
+dev = DEVICE(&(s->lpuart));
+qdev_prop_set_chr(dev, "chardev", serial_hd(STM_NUM_USARTS + 
STM_NUM_UARTS));
+qdev_connect_clock_in(dev, "clk",
+   

[PATCH v2 3/6] hw/char/stm32l4x5_usart: Enable serial read and write

2024-03-24 Thread Arnaud Minier
Implement the ability to read and write characters to the
usart using the serial port.

The character transmission is based on the
cmsdk-apb-uart implementation.

Signed-off-by: Arnaud Minier 
Signed-off-by: Inès Varhol 
---
 hw/char/stm32l4x5_usart.c | 139 ++
 hw/char/trace-events  |   7 ++
 include/hw/char/stm32l4x5_usart.h |   1 +
 3 files changed, 147 insertions(+)

diff --git a/hw/char/stm32l4x5_usart.c b/hw/char/stm32l4x5_usart.c
index 46e69bb096..ec8c2f6e63 100644
--- a/hw/char/stm32l4x5_usart.c
+++ b/hw/char/stm32l4x5_usart.c
@@ -154,6 +154,119 @@ REG32(RDR, 0x24)
 REG32(TDR, 0x28)
 FIELD(TDR, TDR, 0, 9)
 
+static void stm32l4x5_update_irq(Stm32l4x5UsartBaseState *s)
+{
+if (((s->isr & R_ISR_WUF_MASK) && (s->cr3 & R_CR3_WUFIE_MASK))||
+((s->isr & R_ISR_CMF_MASK) && (s->cr1 & R_CR1_CMIE_MASK)) ||
+((s->isr & R_ISR_ABRF_MASK) && (s->cr1 & R_CR1_RXNEIE_MASK))  ||
+((s->isr & R_ISR_EOBF_MASK) && (s->cr1 & R_CR1_EOBIE_MASK))   ||
+((s->isr & R_ISR_RTOF_MASK) && (s->cr1 & R_CR1_RTOIE_MASK))   ||
+((s->isr & R_ISR_CTSIF_MASK) && (s->cr3 & R_CR3_CTSIE_MASK))  ||
+((s->isr & R_ISR_LBDF_MASK) && (s->cr2 & R_CR2_LBDIE_MASK))   ||
+((s->isr & R_ISR_TXE_MASK) && (s->cr1 & R_CR1_TXEIE_MASK))||
+((s->isr & R_ISR_TC_MASK) && (s->cr1 & R_CR1_TCIE_MASK))  ||
+((s->isr & R_ISR_RXNE_MASK) && (s->cr1 & R_CR1_RXNEIE_MASK))  ||
+((s->isr & R_ISR_IDLE_MASK) && (s->cr1 & R_CR1_IDLEIE_MASK))  ||
+((s->isr & R_ISR_ORE_MASK) &&
+((s->cr1 & R_CR1_RXNEIE_MASK) || (s->cr3 & R_CR3_EIE_MASK)))  ||
+/* TODO: Handle NF ? */
+((s->isr & R_ISR_FE_MASK) && (s->cr3 & R_CR3_EIE_MASK))   ||
+((s->isr & R_ISR_PE_MASK) && (s->cr1 & R_CR1_PEIE_MASK))) {
+qemu_irq_raise(s->irq);
+trace_stm32l4x5_usart_irq_raised(s->isr);
+} else {
+qemu_irq_lower(s->irq);
+trace_stm32l4x5_usart_irq_lowered();
+}
+}
+
+static int stm32l4x5_usart_base_can_receive(void *opaque)
+{
+Stm32l4x5UsartBaseState *s = opaque;
+
+if (!(s->isr & R_ISR_RXNE_MASK)) {
+return 1;
+}
+
+return 0;
+}
+
+static void stm32l4x5_usart_base_receive(void *opaque, const uint8_t *buf, int 
size)
+{
+Stm32l4x5UsartBaseState *s = opaque;
+
+if (!((s->cr1 & R_CR1_UE_MASK) && (s->cr1 & R_CR1_RE_MASK))) {
+trace_stm32l4x5_usart_receiver_not_enabled(
+FIELD_EX32(s->cr1, CR1, UE), FIELD_EX32(s->cr1, CR1, RE));
+return;
+}
+
+/* Check if overrun detection is enabled and if there is an overrun */
+if (!(s->cr3 & R_CR3_OVRDIS_MASK) && (s->isr & R_ISR_RXNE_MASK)) {
+/*
+ * A character has been received while
+ * the previous has not been read = Overrun.
+ */
+s->isr |= R_ISR_ORE_MASK;
+trace_stm32l4x5_usart_overrun_detected(s->rdr, *buf);
+} else {
+/* No overrun */
+s->rdr = *buf;
+s->isr |= R_ISR_RXNE_MASK;
+trace_stm32l4x5_usart_rx(s->rdr);
+}
+
+stm32l4x5_update_irq(s);
+}
+
+/* Try to send tx data, and arrange to be called back later if
+ * we can't (ie the char backend is busy/blocking).
+ */
+static gboolean usart_transmit(void *do_not_use, GIOCondition cond, void 
*opaque)
+{
+Stm32l4x5UsartBaseState *s = STM32L4X5_USART_BASE(opaque);
+int ret;
+/* TODO: Handle 9 bits transmission */
+uint8_t ch = s->tdr;
+
+s->watch_tag = 0;
+
+if (!(s->cr1 & R_CR1_TE_MASK) || (s->isr & R_ISR_TXE_MASK)) {
+return G_SOURCE_REMOVE;
+}
+
+ret = qemu_chr_fe_write(>chr, , 1);
+if (ret <= 0) {
+s->watch_tag = qemu_chr_fe_add_watch(>chr, G_IO_OUT | G_IO_HUP,
+ usart_transmit, s);
+if (!s->watch_tag) {
+/* Most common reason to be here is "no chardev backend":
+ * just insta-drain the buffer, so the serial output
+ * goes into a void, rather than blocking the guest.
+ */
+goto buffer_drained;
+}
+/* Transmit pending */
+trace_stm32l4x5_usart_tx_pending();
+return G_SOURCE_REMOVE;
+}
+
+buffer_drained:
+/* Character successfully sent */
+trace_stm32l4x5_usart_tx(ch);
+s->isr |= R_ISR_TC_MASK | R_ISR_TXE_MASK;
+stm32l4x5_update_irq(s);
+return G_SOURCE_REMOVE;
+}
+
+static void usart_cancel_transmit(Stm32l4x5UsartBaseState *s)
+{
+if (s->watch_tag) {
+g_source_remove(s->watch_tag);
+s->watch_tag = 0;
+}
+}
+
 static void stm32l4x5_usart_base_reset_hold(Object *obj)
 {
 Stm32l4x5UsartBaseState *s = STM32L4X5_USART_BASE(obj);
@@ -167,6 +280,22 @@ static void stm32l4x5_usart_base_reset_hold(Object *obj)
 s->isr = 0x02C0;
 s->rdr = 0x;
 s->tdr = 0x;
+
+usart_cancel_transmit(s);
+

[PATCH v2 1/6] hw/misc/stm32l4x5_rcc: Propagate period when enabling a clock

2024-03-24 Thread Arnaud Minier
The "clock_set_mul_div" function doesn't propagate the clock period to
the children if it is changed (e.g. by enabling/disabling
a clock multiplexer).
This was overlooked during the implementation due to late changes.

This commit propagates the change if the multiplier or divider changes.

The usart tests will ensure that this behavior will not regress.

Signed-off-by: Arnaud Minier 
Signed-off-by: Inès Varhol 
---
 hw/misc/stm32l4x5_rcc.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/misc/stm32l4x5_rcc.c b/hw/misc/stm32l4x5_rcc.c
index bc2d63528b..4725ba4f1c 100644
--- a/hw/misc/stm32l4x5_rcc.c
+++ b/hw/misc/stm32l4x5_rcc.c
@@ -59,7 +59,12 @@ static void clock_mux_update(RccClockMuxState *mux, bool 
bypass_source)
 freq_multiplier = mux->divider;
 }
 
-clock_set_mul_div(mux->out, freq_multiplier, mux->multiplier);
+if ((mux->out->multiplier != freq_multiplier) ||
+mux->out->divider != mux->multiplier) {
+clock_set_mul_div(mux->out, freq_multiplier, mux->multiplier);
+clock_propagate(mux->out);
+}
+
 clock_update(mux->out, clock_get(current_source));
 
 src_freq = clock_get_hz(current_source);
-- 
2.34.1




[PATCH v2 2/6] hw/char: Implement STM32L4x5 USART skeleton

2024-03-24 Thread Arnaud Minier
Add the basic infrastructure (register read/write, type...)
to implement the STM32L4x5 USART.

Also create different types for the USART, UART and LPUART
of the STM32L4x5 to deduplicate code and enable the
implementation of different behaviors depending on the type.

Signed-off-by: Arnaud Minier 
Signed-off-by: Inès Varhol 
---
 MAINTAINERS   |   1 +
 hw/char/Kconfig   |   3 +
 hw/char/meson.build   |   1 +
 hw/char/stm32l4x5_usart.c | 395 ++
 hw/char/trace-events  |   4 +
 include/hw/char/stm32l4x5_usart.h |  66 +
 6 files changed, 470 insertions(+)
 create mode 100644 hw/char/stm32l4x5_usart.c
 create mode 100644 include/hw/char/stm32l4x5_usart.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 409d7db4d4..deba4a54ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1128,6 +1128,7 @@ M: Inès Varhol 
 L: qemu-...@nongnu.org
 S: Maintained
 F: hw/arm/stm32l4x5_soc.c
+F: hw/char/stm32l4x5_usart.c
 F: hw/misc/stm32l4x5_exti.c
 F: hw/misc/stm32l4x5_syscfg.c
 F: hw/misc/stm32l4x5_rcc.c
diff --git a/hw/char/Kconfig b/hw/char/Kconfig
index 6b6cf2fc1d..4fd74ea878 100644
--- a/hw/char/Kconfig
+++ b/hw/char/Kconfig
@@ -41,6 +41,9 @@ config VIRTIO_SERIAL
 config STM32F2XX_USART
 bool
 
+config STM32L4X5_USART
+bool
+
 config CMSDK_APB_UART
 bool
 
diff --git a/hw/char/meson.build b/hw/char/meson.build
index 006d20f1e2..e5b13b6958 100644
--- a/hw/char/meson.build
+++ b/hw/char/meson.build
@@ -31,6 +31,7 @@ system_ss.add(when: 'CONFIG_RENESAS_SCI', if_true: 
files('renesas_sci.c'))
 system_ss.add(when: 'CONFIG_SIFIVE_UART', if_true: files('sifive_uart.c'))
 system_ss.add(when: 'CONFIG_SH_SCI', if_true: files('sh_serial.c'))
 system_ss.add(when: 'CONFIG_STM32F2XX_USART', if_true: 
files('stm32f2xx_usart.c'))
+system_ss.add(when: 'CONFIG_STM32L4X5_USART', if_true: 
files('stm32l4x5_usart.c'))
 system_ss.add(when: 'CONFIG_MCHP_PFSOC_MMUART', if_true: 
files('mchp_pfsoc_mmuart.c'))
 system_ss.add(when: 'CONFIG_HTIF', if_true: files('riscv_htif.c'))
 system_ss.add(when: 'CONFIG_GOLDFISH_TTY', if_true: files('goldfish_tty.c'))
diff --git a/hw/char/stm32l4x5_usart.c b/hw/char/stm32l4x5_usart.c
new file mode 100644
index 00..46e69bb096
--- /dev/null
+++ b/hw/char/stm32l4x5_usart.c
@@ -0,0 +1,395 @@
+/*
+ * STM32L4X5 USART (Universal Synchronous Asynchronous Receiver Transmitter)
+ *
+ * Copyright (c) 2023 Arnaud Minier 
+ * Copyright (c) 2023 Inès Varhol 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * The STM32L4X5 USART is heavily inspired by the stm32f2xx_usart
+ * by Alistair Francis.
+ * The reference used is the STMicroElectronics RM0351 Reference manual
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+#include "chardev/char-fe.h"
+#include "chardev/char-serial.h"
+#include "migration/vmstate.h"
+#include "hw/char/stm32l4x5_usart.h"
+#include "hw/clock.h"
+#include "hw/irq.h"
+#include "hw/qdev-clock.h"
+#include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
+#include "hw/registerfields.h"
+#include "trace.h"
+
+
+REG32(CR1, 0x00)
+FIELD(CR1, M1, 28, 1)/* Word length (part 2, see M0)*/
+FIELD(CR1, EOBIE, 27, 1) /* End of Block interrupt enable */
+FIELD(CR1, RTOIE, 26, 1) /* Receiver timeout interrupt enable */
+FIELD(CR1, DEAT, 21, 5)  /* Driver Enable assertion time */
+FIELD(CR1, DEDT, 16, 5)  /* Driver Enable de-assertion time */
+FIELD(CR1, OVER8, 15, 1) /* Oversampling mode */
+FIELD(CR1, CMIE, 14, 1)  /* Character match interrupt enable */
+FIELD(CR1, MME, 13, 1)   /* Mute mode enable */
+FIELD(CR1, M0, 12, 1)/* Word length (part 1, see M1) */
+FIELD(CR1, WAKE, 11, 1)  /* Receiver wakeup method */
+FIELD(CR1, PCE, 10, 1)   /* Parity control enable */
+FIELD(CR1, PS, 9, 1) /* Parity selection */
+FIELD(CR1, PEIE, 8, 1)   /* PE interrupt enable */
+FIELD(CR1, TXEIE, 7, 1)  /* TXE interrupt enable */
+FIELD(CR1, TCIE, 6, 1)   /* Transmission complete interrupt enable */
+FIELD(CR1, RXNEIE, 5, 1) /* RXNE interrupt enable */
+FIELD(CR1, IDLEIE, 4, 1) /* IDLE interrupt enable */
+FIELD(CR1, TE, 3, 1) /* Transmitter enable */
+FIELD(CR1, RE, 2, 1) /* Receiver enable */
+FIELD(CR1, UESM, 1, 1)   /* USART enable in Stop mode */
+FIELD(CR1, UE, 0, 1) /* USART enable */
+REG32(CR2, 0x04)
+FIELD(CR2, ADD_1, 28, 4)/* ADD[7:4] */
+FIELD(CR2, ADD_0, 24, 1)/* ADD[3:0] */
+FIELD(CR2, RTOEN, 23, 1)/* Receiver timeout enable */
+FIELD(CR2, ABRMOD, 21, 2)   /* Auto baud rate mode */
+FIELD(CR2, ABREN, 20, 1)/* Auto baud rate enable */
+FIELD(CR2, MSBFIRST, 19, 1) /* Most significant bit first 

[PATCH v2 0/6] hw/char: Implement the STM32L4x5 USART, UART and LPUART

2024-03-24 Thread Arnaud Minier
This patch adds the STM32L4x5 USART
(Universal Synchronous/Asynchronous Receiver/Transmitter)
device and is part of a series implementing the
STM32L4x5 with a few peripherals.

It implements the necessary functionalities to receive/send
characters over the serial port, which are useful to
communicate with the program currently running.

Many thanks Peter for your review, I think I addressed almost
everything.
I'm just unsure about how to handle the waiting time in the tests.
I understand your concerns about the unreliability of using the wallclock
time but I don't understand how using clock_step() would make it
more reliable. We will always be waiting on something
that is out of our control (i.e. the OS).
I increased the delay from 5s to 10min to match the microbit test
and added a comment (I paraphrased your comment, is that okay ?).

I also saw that Philippe Mathieu-Daudé have sent a patchset with
the first commit of this patchset and another commit to make
clock_set_mul_div() return a boolean.
If this is merged before this patchset (which will probably be
the case), I will remove the first commit.

Changes from v1 to v2:
- Use asynchronous transmission for serial communication
  (based on cmsdk-apb-uart implementation)
- Use qemu_log_mask instead of error_report
- Squash the commit that renamed the base struct
- Use switch statements where appropriate
- Fix RDR and TDR mask size
- Increase time limit in tests
- Remove the global qtest in the tests
- Use assert when checking the interrupt number in the tests
- Correct usage of g_autofree in the SoC

Arnaud Minier (6):
  hw/misc/stm32l4x5_rcc: Propagate period when enabling a clock
  hw/char: Implement STM32L4x5 USART skeleton
  hw/char/stm32l4x5_usart: Enable serial read and write
  hw/char/stm32l4x5_usart: Add options for serial parameters setting
  hw/arm: Add the USART to the stm32l4x5 SoC
  tests/qtest: Add tests for the STM32L4x5 USART

 MAINTAINERS|   1 +
 docs/system/arm/b-l475e-iot01a.rst |   2 +-
 hw/arm/Kconfig |   1 +
 hw/arm/stm32l4x5_soc.c |  82 +++-
 hw/char/Kconfig|   3 +
 hw/char/meson.build|   1 +
 hw/char/stm32l4x5_usart.c  | 632 +
 hw/char/trace-events   |  12 +
 hw/misc/stm32l4x5_rcc.c|   7 +-
 include/hw/arm/stm32l4x5_soc.h |  13 +
 include/hw/char/stm32l4x5_usart.h  |  67 +++
 tests/qtest/meson.build|   3 +-
 tests/qtest/stm32l4x5_usart-test.c | 326 +++
 13 files changed, 1141 insertions(+), 9 deletions(-)
 create mode 100644 hw/char/stm32l4x5_usart.c
 create mode 100644 include/hw/char/stm32l4x5_usart.h
 create mode 100644 tests/qtest/stm32l4x5_usart-test.c

-- 
2.34.1




Re: [PATCH 3/3] target/hppa: fix building gva for wide mode

2024-03-24 Thread Helge Deller

On 3/24/24 09:09, Sven Schnelle wrote:

64 Bit hppa no longer has a fixed 32/32 bit split between space and
offset. Instead it uses 42 bits for the offset. The lower 10 bits of
the space are always zero, leaving 22 bits actually used. Simply or
the values together to build the gva.

Signed-off-by: Sven Schnelle 


Reviewed-by: Helge Deller 
Tested-by: Helge Deller 

Helge


---
  target/hppa/mem_helper.c | 13 +++--
  1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 84785b5a5c..6f895fced7 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -523,13 +523,16 @@ void HELPER(itlbp_pa11)(CPUHPPAState *env, target_ulong 
addr, target_ulong reg)
  }

  static void itlbt_pa20(CPUHPPAState *env, target_ulong r1,
-   target_ulong r2, vaddr va_b)
+   target_ulong r2, uint64_t spc, uint64_t off)
  {
  HPPATLBEntry *ent;
-vaddr va_e;
+vaddr va_b, va_e;
  uint64_t va_size;
  int mask_shift;

+va_b = off & gva_offset_mask(env->psw);
+va_b |= spc << 32;
+
  mask_shift = 2 * (r1 & 0xf);
  va_size = (uint64_t)TARGET_PAGE_SIZE << mask_shift;
  va_b &= -va_size;
@@ -569,14 +572,12 @@ static void itlbt_pa20(CPUHPPAState *env, target_ulong r1,

  void HELPER(idtlbt_pa20)(CPUHPPAState *env, target_ulong r1, target_ulong r2)
  {
-vaddr va_b = deposit64(env->cr[CR_IOR], 32, 32, env->cr[CR_ISR]);
-itlbt_pa20(env, r1, r2, va_b);
+itlbt_pa20(env, r1, r2, env->cr[CR_ISR], env->cr[CR_IOR]);
  }

  void HELPER(iitlbt_pa20)(CPUHPPAState *env, target_ulong r1, target_ulong r2)
  {
-vaddr va_b = deposit64(env->cr[CR_IIAOQ], 32, 32, env->cr[CR_IIASQ]);
-itlbt_pa20(env, r1, r2, va_b);
+itlbt_pa20(env, r1, r2, env->cr[CR_IIASQ], env->cr[CR_IIAOQ]);
  }

  /* Purge (Insn/Data) TLB. */





Re: [PATCH 2/3] target/hppa: mask offset bits in gva

2024-03-24 Thread Helge Deller

On 3/24/24 09:09, Sven Schnelle wrote:

The CPU seems to mask a few bits in the offset when running
under HP-UX. ISR/IOR register contents for an address in
the processor HPA (0xfffa) on my C8000 and J6750:

running on Linux: 3fff c000fffa0500
running on HP-UX: 301f c000fffa0500

I haven't found how this is switched (guess some diag in the
firmware), but linux + seabios seems to handle that as well,
so lets mask out the additional bits.

Signed-off-by: Sven Schnelle 


I've seen the issue on HP-UX too, and can confirm the patch does
not break existing 32- and 64-bit Linux installations, so:

Tested-by: Helge Deller 

Thanks!
Helge



---
  target/hppa/cpu.h | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index a072d0bb63..9bc4d208fa 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -283,12 +283,13 @@ static inline int HPPA_BTLB_ENTRIES(CPUHPPAState *env)

  void hppa_translate_init(void);

+#define HPPA_GVA_OFFSET_MASK64 0x301f
  #define CPU_RESOLVING_TYPE TYPE_HPPA_CPU

  static inline uint64_t gva_offset_mask(target_ulong psw)
  {
  return (psw & PSW_W
-? MAKE_64BIT_MASK(0, 62)
+? HPPA_GVA_OFFSET_MASK64
  : MAKE_64BIT_MASK(0, 32));
  }






[PATCH] docs/system/ppc/amigang.rst: Fix formatting

2024-03-24 Thread BALATON Zoltan
Add missing space to fix character formatting where it was missed in
two places.

Fixes: 623d9065b6 (docs/system/ppc: Document running Linux on AmigaNG machines)
Signed-off-by: BALATON Zoltan 
---
 docs/system/ppc/amigang.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docs/system/ppc/amigang.rst b/docs/system/ppc/amigang.rst
index ba1a3d80b9..e2c9cb74b7 100644
--- a/docs/system/ppc/amigang.rst
+++ b/docs/system/ppc/amigang.rst
@@ -16,7 +16,7 @@ firmware to support AmigaOS 4.
 Emulated devices
 
 
- * PowerPC 7457 CPU (can also use``-cpu g3, 750cxe, 750fx`` or ``750gx``)
+ * PowerPC 7457 CPU (can also use ``-cpu g3, 750cxe, 750fx`` or ``750gx``)
  * Articia S north bridge
  * VIA VT82C686B south bridge
  * PCI VGA compatible card (guests may need other card instead)
@@ -73,7 +73,7 @@ https://www.powerdeveloper.org/platforms/pegasos/schematics.
 Emulated devices
 
 
- * PowerPC 7457 CPU (can also use``-cpu g3`` or ``750cxe``)
+ * PowerPC 7457 CPU (can also use ``-cpu g3`` or ``750cxe``)
  * Marvell MV64361 Discovery II north bridge
  * VIA VT8231 south bridge
  * PCI VGA compatible card (guests may need other card instead)
-- 
2.30.9




Re: [PATCH 1/3] target/hppa: use gva_offset_mask() everywhere

2024-03-24 Thread Helge Deller

On 3/24/24 09:09, Sven Schnelle wrote:

move it to cpu.h, so it can also be used in hppa_form_gva_psw()

Signed-off-by: Sven Schnelle 


Reviewed-by: Helge Deller 

Helge


---
  target/hppa/cpu.h   | 10 --
  target/hppa/translate.c | 12 +++-
  2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index a92dc352cb..a072d0bb63 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -285,14 +285,20 @@ void hppa_translate_init(void);

  #define CPU_RESOLVING_TYPE TYPE_HPPA_CPU

+static inline uint64_t gva_offset_mask(target_ulong psw)
+{
+return (psw & PSW_W
+? MAKE_64BIT_MASK(0, 62)
+: MAKE_64BIT_MASK(0, 32));
+}
+
  static inline target_ulong hppa_form_gva_psw(target_ulong psw, uint64_t spc,
   target_ulong off)
  {
  #ifdef CONFIG_USER_ONLY
  return off;
  #else
-off &= psw & PSW_W ? MAKE_64BIT_MASK(0, 62) : MAKE_64BIT_MASK(0, 32);
-return spc | off;
+return spc | (off & gva_offset_mask(psw));
  #endif
  }

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 19594f917e..0af125ed74 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -586,17 +586,10 @@ static bool nullify_end(DisasContext *ctx)
  return true;
  }

-static uint64_t gva_offset_mask(DisasContext *ctx)
-{
-return (ctx->tb_flags & PSW_W
-? MAKE_64BIT_MASK(0, 62)
-: MAKE_64BIT_MASK(0, 32));
-}
-
  static void copy_iaoq_entry(DisasContext *ctx, TCGv_i64 dest,
  uint64_t ival, TCGv_i64 vval)
  {
-uint64_t mask = gva_offset_mask(ctx);
+uint64_t mask = gva_offset_mask(ctx->tb_flags);

  if (ival != -1) {
  tcg_gen_movi_i64(dest, ival & mask);
@@ -1403,7 +1396,8 @@ static void form_gva(DisasContext *ctx, TCGv_i64 *pgva, 
TCGv_i64 *pofs,

  *pofs = ofs;
  *pgva = addr = tcg_temp_new_i64();
-tcg_gen_andi_i64(addr, modify <= 0 ? ofs : base, gva_offset_mask(ctx));
+tcg_gen_andi_i64(addr, modify <= 0 ? ofs : base,
+ gva_offset_mask(ctx->tb_flags));
  #ifndef CONFIG_USER_ONLY
  if (!is_phys) {
  tcg_gen_or_i64(addr, addr, space_select(ctx, sp, base));





[PATCH] chardev/char-win-stdio: Fix keyboard input after exit Qemu on

2024-03-24 Thread Irina Ryapolova
After exit Qemu need to return the terminal to the default state.

Signed-off-by: Irina Ryapolova 
---
 chardev/char-win-stdio.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/chardev/char-win-stdio.c b/chardev/char-win-stdio.c
index 1a18999e78..4fa2c3de8b 100644
--- a/chardev/char-win-stdio.c
+++ b/chardev/char-win-stdio.c
@@ -220,6 +220,7 @@ err1:
 static void char_win_stdio_finalize(Object *obj)
 {
 WinStdioChardev *stdio = WIN_STDIO_CHARDEV(obj);
+DWORD dwMode;
 
 if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) {
 CloseHandle(stdio->hInputReadyEvent);
@@ -230,6 +231,10 @@ static void char_win_stdio_finalize(Object *obj)
 if (stdio->hInputThread != INVALID_HANDLE_VALUE) {
 TerminateThread(stdio->hInputThread, 0);
 }
+
+GetConsoleMode(stdio->hStdIn, );
+dwMode &= ~ENABLE_VIRTUAL_TERMINAL_INPUT;
+SetConsoleMode(stdio->hStdIn, dwMode);
 }
 
 static int win_stdio_write(Chardev *chr, const uint8_t *buf, int len)
-- 
2.25.1




[PATCH v3 1/2] target/riscv/csr.c: Add functional of hvictl CSR

2024-03-24 Thread Irina Ryapolova
CSR hvictl (Hypervisor Virtual Interrupt Control) provides further flexibility
for injecting interrupts into VS level in situations not fully supported by the
facilities described thus far, but only with more active involvement of the 
hypervisor.

A hypervisor must use hvictl for any of the following:
• asserting for VS level a major interrupt not supported by hvien and hvip;
• implementing configurability of priorities at VS level for major interrupts 
beyond those sup-
ported by hviprio1 and hviprio2; or
• emulating an external interrupt controller for a virtual hart without the use 
of an IMSIC’s
guest interrupt file, while also supporting configurable priorities both for 
external interrupts
and for major interrupts to the virtual hart.

All hvictl fields together can affect the value of CSR vstopi (Virtual 
Supervisor Top Interrupt)
and therefore the interrupt identity reported in vscause when an interrupt 
traps to VS-mode.
When hvictl.VTI = 1, the absence of an interrupt for VS level can be indicated 
only by setting
hvictl.IID = 9. Software might want to use the pair IID = 9, IPRIO = 0 
generally to represent
no interrupt in hvictl.

(See riscv-interrupts-1.0: Interrupts at VS level)

Signed-off-by: Irina Ryapolova 
---
Changes for v2:
  -added more information in commit message
Changes for v3:
  -applied patch in master
---
 target/riscv/csr.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 726096444f..4c2cbcd59f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3613,6 +3613,21 @@ static RISCVException write_hvictl(CPURISCVState *env, 
int csrno,
target_ulong val)
 {
 env->hvictl = val & HVICTL_VALID_MASK;
+if (env->hvictl & HVICTL_VTI)
+{
+uint32_t hviid = get_field(env->hvictl, HVICTL_IID);
+uint32_t hviprio = get_field(env->hvictl, HVICTL_IPRIO);
+/* the pair IID = 9, IPRIO = 0 generally to represent no interrupt in 
hvictl. */
+if (!(hviid == IRQ_S_EXT && hviprio == 0)) {
+uint64_t new_val = BIT(hviid) ;
+ if (new_val & S_MODE_INTERRUPTS) {
+rmw_hvip64(env, csrno, NULL, new_val << 1, new_val << 1);
+} else if (new_val & LOCAL_INTERRUPTS) {
+rmw_hvip64(env, csrno, NULL, new_val, new_val);
+}
+}
+}
+
 return RISCV_EXCP_NONE;
 }
 
-- 
2.25.1




[PATCH v3 2/2] target/riscv/csr: Added the ability to delegate LCOFI to VS

2024-03-24 Thread Irina Ryapolova
From: Vadim Shakirov 

In the AIA specification in the paragraph "Virtual interrupts for VS level"
it is indicated for interrupts 13-63: if the bit in hideleg is enabled,
then the corresponding vsip and vsie bits are aliases to sip and sie

Signed-off-by: Vadim Shakirov 
Reviewed-by: Alistair Francis 
---
 target/riscv/csr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 4c2cbcd59f..38548a01d9 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1150,7 +1150,7 @@ static RISCVException write_stimecmph(CPURISCVState *env, 
int csrno,
 static const uint64_t delegable_ints =
 S_MODE_INTERRUPTS | VS_MODE_INTERRUPTS | MIP_LCOFIP;
 static const uint64_t vs_delegable_ints =
-(VS_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & ~MIP_LCOFIP;
+VS_MODE_INTERRUPTS | LOCAL_INTERRUPTS;
 static const uint64_t all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS |
  HS_MODE_INTERRUPTS | LOCAL_INTERRUPTS;
 #define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \
-- 
2.25.1




[PATCH] target/riscv: Fix mode in riscv_tlb_fill

2024-03-24 Thread Irina Ryapolova
Need to convert mmu_idx to privilege mode for PMP function.

Signed-off-by: Irina Ryapolova 
---
 target/riscv/cpu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index ce7322011d..fc090d729a 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1315,7 +1315,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 bool two_stage_lookup = mmuidx_2stage(mmu_idx);
 bool two_stage_indirect_error = false;
 int ret = TRANSLATE_FAIL;
-int mode = mmu_idx;
+int mode = mmuidx_priv(mmu_idx);
 /* default TLB page size */
 target_ulong tlb_size = TARGET_PAGE_SIZE;
 
-- 
2.25.1




Re: [PULL 00/15] riscv-to-apply queue

2024-03-24 Thread Michael Tokarev

22.03.2024 22:46, Daniel Henrique Barboza :



On 3/22/24 14:16, Michael Tokarev wrote:

22.03.2024 11:53, Alistair Francis :


RISC-V PR for 9.0

* Do not enable all named features by default
* A range of Vector fixes
* Update APLIC IDC after claiming iforce register
* Remove the dependency of Zvfbfmin to Zfbfmin
* Fix mode in riscv_tlb_fill
* Fix timebase-frequency when using KVM acceleration


Should something from there be picked up for stable (8.2 and probably 7.2)?


Ignore the "Do not enable all named features by default" since it's fixing 
something
that were added in 9.0.

The rest you can pick it up to 8.2 at least. Thanks,


Unfortunately this doesn't quite work, the following changes
fail to apply to 8.2:

929e521a47 target/riscv: always clear vstart for ldst_whole insns
b46631f122 target/riscv: remove 'over' brconds from vector trans
d57dfe4b37 trans_rvv.c.inc: remove redundant mark_vs_dirty() calls
bac802ada8 target/riscv: enable 'vstart_eq_zero' in the end of insns
385e575cd5 target/riscv/kvm: fix timebase-frequency when using KVM acceleration

I tried to back-port at least the first one but it turned out to be
another failure.  Didn't try looking at the rest.

If these really should be in 8.2 (it's your guys to decide, not me),
I need help with back-porting these to 8.2 (and/or cherry-picking
additional patches from master).

Thanks,

/mjt



Daniel Henrique Barboza (10):
   target/riscv: do not enable all named features by default
   target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX()
   trans_rvv.c.inc: set vstart = 0 in int scalar move insns
   target/riscv/vector_helper.c: fix 'vmvr_v' memcpy endianess
   target/riscv: always clear vstart in whole vec move insns
   target/riscv: always clear vstart for ldst_whole insns
   target/riscv/vector_helpers: do early exit when vstart >= vl
   target/riscv: remove 'over' brconds from vector trans
   trans_rvv.c.inc: remove redundant mark_vs_dirty() calls
   target/riscv/vector_helper.c: optimize loops in ldst helpers

Frank Chang (1):
   hw/intc: Update APLIC IDC after claiming iforce register

Irina Ryapolova (1):
   target/riscv: Fix mode in riscv_tlb_fill

Ivan Klokov (1):
   target/riscv: enable 'vstart_eq_zero' in the end of insns

Max Chou (1):
   target/riscv: rvv: Remove the dependency of Zvfbfmin to Zfbfmin

Yong-Xuan Wang (1):
   target/riscv/kvm: fix timebase-frequency when using KVM acceleration









Re: [PATCH v2 1/3] ui/cocoa: Fix aspect ratio

2024-03-24 Thread Peter Maydell
On Sat, 23 Mar 2024 at 06:20, Akihiko Odaki  wrote:
>
> [NSWindow setContentAspectRatio:] does not trigger window resize itself,
> so the wrong aspect ratio will persist if nothing resizes the window.
> Call [NSWindow setContentSize:] in such a case.
>
> Fixes: 91aa508d0274 ("ui/cocoa: Let the platform toggle fullscreen")
> Signed-off-by: Akihiko Odaki 
> ---


Reviewed-by: Peter Maydell 

thanks
-- PMM



[PATCH v1 1/1] virtio-snd: rewrite invalid tx/rx message handling

2024-03-24 Thread Manos Pitsidianakis
The current handling of invalid virtqueue elements inside the TX/RX virt
queue handlers is wrong.

They are added in a per-stream invalid queue to be processed after the
handler is done examining each message, but the invalid message might
not be specifying any stream_id; which means it's invalid to add it to
any stream->invalid queue since stream could be NULL at this point.

This commit moves the invalid queue to the VirtIOSound struct which
guarantees there will always be a valid temporary place to store them
inside the tx/rx handlers. The queue will be emptied before the handler
returns, so the queue must be empty at any other point of the device's
lifetime.

Signed-off-by: Manos Pitsidianakis 
---
 include/hw/audio/virtio-snd.h |  16 +++-
 hw/audio/virtio-snd.c | 137 +++---
 2 files changed, 77 insertions(+), 76 deletions(-)

diff --git a/include/hw/audio/virtio-snd.h b/include/hw/audio/virtio-snd.h
index 3d79181364..8dafedb276 100644
--- a/include/hw/audio/virtio-snd.h
+++ b/include/hw/audio/virtio-snd.h
@@ -151,7 +151,6 @@ struct VirtIOSoundPCMStream {
 QemuMutex queue_mutex;
 bool active;
 QSIMPLEQ_HEAD(, VirtIOSoundPCMBuffer) queue;
-QSIMPLEQ_HEAD(, VirtIOSoundPCMBuffer) invalid;
 };
 
 /*
@@ -223,6 +222,21 @@ struct VirtIOSound {
 QemuMutex cmdq_mutex;
 QTAILQ_HEAD(, virtio_snd_ctrl_command) cmdq;
 bool processing_cmdq;
+/*
+ * Convenience queue to keep track of invalid tx/rx queue messages inside
+ * the tx/rx callbacks.
+ *
+ * In the callbacks as a first step we are emptying the virtqueue to handle
+ * each message and we cannot add an invalid message back to the queue: we
+ * would re-process it in subsequent loop iterations.
+ *
+ * Instead, we add them to this queue and after finishing examining every
+ * virtqueue element, we inform the guest for each invalid message.
+ *
+ * This queue must be empty at all times except for inside the tx/rx
+ * callbacks.
+ */
+QSIMPLEQ_HEAD(, VirtIOSoundPCMBuffer) invalid;
 };
 
 struct virtio_snd_ctrl_command {
diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
index 30493f06a8..90d9a2796e 100644
--- a/hw/audio/virtio-snd.c
+++ b/hw/audio/virtio-snd.c
@@ -456,7 +456,6 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, 
uint32_t stream_id)
 stream->s = s;
 qemu_mutex_init(>queue_mutex);
 QSIMPLEQ_INIT(>queue);
-QSIMPLEQ_INIT(>invalid);
 
 /*
  * stream_id >= s->snd_conf.streams was checked before so this is
@@ -611,9 +610,6 @@ static size_t 
virtio_snd_pcm_get_io_msgs_count(VirtIOSoundPCMStream *stream)
 QSIMPLEQ_FOREACH_SAFE(buffer, >queue, entry, next) {
 count += 1;
 }
-QSIMPLEQ_FOREACH_SAFE(buffer, >invalid, entry, next) {
-count += 1;
-}
 }
 return count;
 }
@@ -831,47 +827,36 @@ static void virtio_snd_handle_event(VirtIODevice *vdev, 
VirtQueue *vq)
 trace_virtio_snd_handle_event();
 }
 
+/*
+ * Must only be called if vsnd->invalid is not empty.
+ */
 static inline void empty_invalid_queue(VirtIODevice *vdev, VirtQueue *vq)
 {
 VirtIOSoundPCMBuffer *buffer = NULL;
-VirtIOSoundPCMStream *stream = NULL;
 virtio_snd_pcm_status resp = { 0 };
 VirtIOSound *vsnd = VIRTIO_SND(vdev);
-bool any = false;
 
-for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) {
-stream = vsnd->pcm->streams[i];
-if (stream) {
-any = false;
-WITH_QEMU_LOCK_GUARD(>queue_mutex) {
-while (!QSIMPLEQ_EMPTY(>invalid)) {
-buffer = QSIMPLEQ_FIRST(>invalid);
-if (buffer->vq != vq) {
-break;
-}
-any = true;
-resp.status = cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
-iov_from_buf(buffer->elem->in_sg,
- buffer->elem->in_num,
- 0,
- ,
- sizeof(virtio_snd_pcm_status));
-virtqueue_push(vq,
-   buffer->elem,
-   sizeof(virtio_snd_pcm_status));
-QSIMPLEQ_REMOVE_HEAD(>invalid, entry);
-virtio_snd_pcm_buffer_free(buffer);
-}
-if (any) {
-/*
- * Notify vq about virtio_snd_pcm_status responses.
- * Buffer responses must be notified separately later.
- */
-virtio_notify(vdev, vq);
-}
-}
-}
+g_assert(!QSIMPLEQ_EMPTY(>invalid));
+
+while (!QSIMPLEQ_EMPTY(>invalid)) {
+buffer = QSIMPLEQ_FIRST(>invalid);
+/* If buffer->vq != vq, our logic is fundamentally wrong, so bail out 
*/
+

[PATCH v1 0/1] virtio-snd: fix invalid tx/rx message handling logic

2024-03-24 Thread Manos Pitsidianakis
This is a logic fix for the error handling in the TX/RX virt queue 
handlers. A potential invalid address dereference was reported and fixed 
by Zheyu Ma in <20240322110827.568412-1-zheyum...@gmail.com>. This patch 
moves the invalid message storage from the stream structs to the virtio 
device struct to

1. make such bug impossible
2. reply to invalid messages again with VIRTIO_SND_S_BAD_MSG, which was 
not possible before.

Patch based on master base-commit: 853546f8128476eefb701d4a55b2781bb3a46faa
with the following patch applied:

  Subject: [PATCH v2] virtio-snd: Enhance error handling for invalid
   transfers
  From: Zheyu Ma 
  Date: Fri, 22 Mar 2024 12:08:27 +0100
  Message-Id: <20240322110827.568412-1-zheyum...@gmail.com>


Manos Pitsidianakis (1):
  virtio-snd: rewrite invalid tx/rx message handling

 include/hw/audio/virtio-snd.h |  16 +++-
 hw/audio/virtio-snd.c | 137 +++---
 2 files changed, 77 insertions(+), 76 deletions(-)


base-commit: 853546f8128476eefb701d4a55b2781bb3a46faa
prerequisite-patch-id: 8209301569bd30ba806d06b3452a2f3156503a7a
-- 
γαῖα πυρί μιχθήτω




Re: [PATCH-for-9.1 25/27] target/tricore: Convert to TCGCPUOps::get_cpu_state()

2024-03-24 Thread Bastian Koppelmann
On Tue, Mar 19, 2024 at 04:42:54PM +0100, Philippe Mathieu-Daudé wrote:
> Convert cpu_get_tb_cpu_state() to TCGCPUOps::get_cpu_state().
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/tricore/cpu.h | 12 
>  target/tricore/cpu.c | 13 +
>  2 files changed, 13 insertions(+), 12 deletions(-)

Reviewed-by: Bastian Koppelmann 

Cheers,
Bastian



Re: [PATCH] target/tricore/helper: Use correct string format in cpu_tlb_fill()

2024-03-24 Thread Bastian Koppelmann
On Tue, Mar 19, 2024 at 06:14:13AM +0100, Philippe Mathieu-Daudé wrote:
> 'address' got converted from target_ulong to vaddr in commit
> 68d6eee73c ("target/tricore: Convert to CPUClass::tlb_fill").
> Use the corresponding format string to avoid casting.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/tricore/helper.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Bastian Koppelmann 

Cheers,
Bastian



[PATCH] hw/net/net_tx_pkt: Fix virtio header without checksum offloading

2024-03-24 Thread Akihiko Odaki
It is incorrect to have the VIRTIO_NET_HDR_F_NEEDS_CSUM set when
checksum offloading is disabled so clear the bit. Set the
VIRTIO_NET_HDR_F_DATA_VALID bit instead to tell the checksum is valid.

TCP/UDP checksum is usually offloaded when the peer requires virtio
headers because they can instruct the peer to compute checksum. However,
igb disables TX checksum offloading when a VF is enabled whether the
peer requires virtio headers because a transmitted packet can be routed
to it and it expects the packet has a proper checksum. Therefore, it
is necessary to have a correct virtio header even when checksum
offloading is disabled.

A real TCP/UDP checksum will be computed and saved in the buffer when
checksum offloading is disabled. The virtio specification requires to
set the packet checksum stored in the buffer to the TCP/UDP pseudo
header when the VIRTIO_NET_HDR_F_NEEDS_CSUM bit is set so the bit must
be cleared in that case.

The VIRTIO_NET_HDR_F_NEEDS_CSUM bit also tells to skip checksum
validation. Even if checksum offloading is disabled, it is desirable to
skip checksum validation because the checksum is always correct. Use the
VIRTIO_NET_HDR_F_DATA_VALID bit to claim the validity of the checksum.

Fixes: ffbd2dbd8e64 ("e1000e: Perform software segmentation for loopback")
Buglink: https://issues.redhat.com/browse/RHEL-23067
Signed-off-by: Akihiko Odaki 
---
 hw/net/net_tx_pkt.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
index 2e5f58b3c9cc..c225cf706513 100644
--- a/hw/net/net_tx_pkt.c
+++ b/hw/net/net_tx_pkt.c
@@ -833,6 +833,9 @@ bool net_tx_pkt_send_custom(struct NetTxPkt *pkt, bool 
offload,
 
 if (offload || gso_type == VIRTIO_NET_HDR_GSO_NONE) {
 if (!offload && pkt->virt_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+pkt->virt_hdr.flags =
+(pkt->virt_hdr.flags & ~VIRTIO_NET_HDR_F_NEEDS_CSUM) |
+VIRTIO_NET_HDR_F_DATA_VALID;
 net_tx_pkt_do_sw_csum(pkt, >vec[NET_TX_PKT_L2HDR_FRAG],
   pkt->payload_frags + 
NET_TX_PKT_PL_START_FRAG - 1,
   pkt->payload_len);

---
base-commit: ba49d760eb04630e7b15f423ebecf6c871b8f77b
change-id: 20240324-tx-c57d3c22ad73

Best regards,
-- 
Akihiko Odaki 




[PATCH 3/3] target/hppa: fix building gva for wide mode

2024-03-24 Thread Sven Schnelle
64 Bit hppa no longer has a fixed 32/32 bit split between space and
offset. Instead it uses 42 bits for the offset. The lower 10 bits of
the space are always zero, leaving 22 bits actually used. Simply or
the values together to build the gva.

Signed-off-by: Sven Schnelle 
---
 target/hppa/mem_helper.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 84785b5a5c..6f895fced7 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -523,13 +523,16 @@ void HELPER(itlbp_pa11)(CPUHPPAState *env, target_ulong 
addr, target_ulong reg)
 }
 
 static void itlbt_pa20(CPUHPPAState *env, target_ulong r1,
-   target_ulong r2, vaddr va_b)
+   target_ulong r2, uint64_t spc, uint64_t off)
 {
 HPPATLBEntry *ent;
-vaddr va_e;
+vaddr va_b, va_e;
 uint64_t va_size;
 int mask_shift;
 
+va_b = off & gva_offset_mask(env->psw);
+va_b |= spc << 32;
+
 mask_shift = 2 * (r1 & 0xf);
 va_size = (uint64_t)TARGET_PAGE_SIZE << mask_shift;
 va_b &= -va_size;
@@ -569,14 +572,12 @@ static void itlbt_pa20(CPUHPPAState *env, target_ulong r1,
 
 void HELPER(idtlbt_pa20)(CPUHPPAState *env, target_ulong r1, target_ulong r2)
 {
-vaddr va_b = deposit64(env->cr[CR_IOR], 32, 32, env->cr[CR_ISR]);
-itlbt_pa20(env, r1, r2, va_b);
+itlbt_pa20(env, r1, r2, env->cr[CR_ISR], env->cr[CR_IOR]);
 }
 
 void HELPER(iitlbt_pa20)(CPUHPPAState *env, target_ulong r1, target_ulong r2)
 {
-vaddr va_b = deposit64(env->cr[CR_IIAOQ], 32, 32, env->cr[CR_IIASQ]);
-itlbt_pa20(env, r1, r2, va_b);
+itlbt_pa20(env, r1, r2, env->cr[CR_IIASQ], env->cr[CR_IIAOQ]);
 }
 
 /* Purge (Insn/Data) TLB. */
-- 
2.43.2




[PATCH 0/3] few hppa fixes for 64bit mode

2024-03-24 Thread Sven Schnelle
Hi,

in preparation of getting 64bit HP-UX running in qemu, here are a few fixes
to make HP-UX progress a bit further.

Sven Schnelle (3):
  target/hppa: use gva_offset_mask() everywhere
  target/hppa: mask offset bits in gva
  target/hppa: fix building gva for wide mode

 target/hppa/cpu.h| 11 +--
 target/hppa/mem_helper.c | 13 +++--
 target/hppa/translate.c  | 12 +++-
 3 files changed, 19 insertions(+), 17 deletions(-)

-- 
2.43.2




[PATCH 2/3] target/hppa: mask offset bits in gva

2024-03-24 Thread Sven Schnelle
The CPU seems to mask a few bits in the offset when running
under HP-UX. ISR/IOR register contents for an address in
the processor HPA (0xfffa) on my C8000 and J6750:

running on Linux: 3fff c000fffa0500
running on HP-UX: 301f c000fffa0500

I haven't found how this is switched (guess some diag in the
firmware), but linux + seabios seems to handle that as well,
so lets mask out the additional bits.

Signed-off-by: Sven Schnelle 
---
 target/hppa/cpu.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index a072d0bb63..9bc4d208fa 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -283,12 +283,13 @@ static inline int HPPA_BTLB_ENTRIES(CPUHPPAState *env)
 
 void hppa_translate_init(void);
 
+#define HPPA_GVA_OFFSET_MASK64 0x301f
 #define CPU_RESOLVING_TYPE TYPE_HPPA_CPU
 
 static inline uint64_t gva_offset_mask(target_ulong psw)
 {
 return (psw & PSW_W
-? MAKE_64BIT_MASK(0, 62)
+? HPPA_GVA_OFFSET_MASK64
 : MAKE_64BIT_MASK(0, 32));
 }
 
-- 
2.43.2




[PATCH 1/3] target/hppa: use gva_offset_mask() everywhere

2024-03-24 Thread Sven Schnelle
move it to cpu.h, so it can also be used in hppa_form_gva_psw()

Signed-off-by: Sven Schnelle 
---
 target/hppa/cpu.h   | 10 --
 target/hppa/translate.c | 12 +++-
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index a92dc352cb..a072d0bb63 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -285,14 +285,20 @@ void hppa_translate_init(void);
 
 #define CPU_RESOLVING_TYPE TYPE_HPPA_CPU
 
+static inline uint64_t gva_offset_mask(target_ulong psw)
+{
+return (psw & PSW_W
+? MAKE_64BIT_MASK(0, 62)
+: MAKE_64BIT_MASK(0, 32));
+}
+
 static inline target_ulong hppa_form_gva_psw(target_ulong psw, uint64_t spc,
  target_ulong off)
 {
 #ifdef CONFIG_USER_ONLY
 return off;
 #else
-off &= psw & PSW_W ? MAKE_64BIT_MASK(0, 62) : MAKE_64BIT_MASK(0, 32);
-return spc | off;
+return spc | (off & gva_offset_mask(psw));
 #endif
 }
 
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 19594f917e..0af125ed74 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -586,17 +586,10 @@ static bool nullify_end(DisasContext *ctx)
 return true;
 }
 
-static uint64_t gva_offset_mask(DisasContext *ctx)
-{
-return (ctx->tb_flags & PSW_W
-? MAKE_64BIT_MASK(0, 62)
-: MAKE_64BIT_MASK(0, 32));
-}
-
 static void copy_iaoq_entry(DisasContext *ctx, TCGv_i64 dest,
 uint64_t ival, TCGv_i64 vval)
 {
-uint64_t mask = gva_offset_mask(ctx);
+uint64_t mask = gva_offset_mask(ctx->tb_flags);
 
 if (ival != -1) {
 tcg_gen_movi_i64(dest, ival & mask);
@@ -1403,7 +1396,8 @@ static void form_gva(DisasContext *ctx, TCGv_i64 *pgva, 
TCGv_i64 *pofs,
 
 *pofs = ofs;
 *pgva = addr = tcg_temp_new_i64();
-tcg_gen_andi_i64(addr, modify <= 0 ? ofs : base, gva_offset_mask(ctx));
+tcg_gen_andi_i64(addr, modify <= 0 ? ofs : base,
+ gva_offset_mask(ctx->tb_flags));
 #ifndef CONFIG_USER_ONLY
 if (!is_phys) {
 tcg_gen_or_i64(addr, addr, space_select(ctx, sp, base));
-- 
2.43.2