Re: [RFC PATCH v4 4/4] tests/avocado: Add test for amigaone board

2023-10-17 Thread Thomas Huth

Please add a short patch description if this moves from RFC to a real patch

On 17/10/2023 21.06, BALATON Zoltan wrote:

Signed-off-by: BALATON Zoltan 
---
I have no idea if this works so testing and corrections are welcome


Why don't you test it on your own? I think this should be sufficient:

 make check-avocado AVOCADO_TAGS=machine:amigaone


but this could be a basic test. Booting further is a bit more involved
as we'd need alternative VGA BIOS and selecting menu items in the
firmware to allow CD boot so I did not try to automate that.

This could be simpler if the u-boot-amigaone.bin could be added to
pc-bios. It's GPL so should be OK to include and distribute but irs
sources seem to be lost and could not be recovered or reconstructed so
we only have this binary. Who should be able to decide about that?


I'm sorry, but if the sources are not available anymore, then I think it 
will not be possible to ship the binary in the QEMU tarball - since the GPL 
requires that the distributor of the binary can also provide the sources on 
request.


 Thomas




Re: [PATCH] vhost: Perform memory section dirty scans once per iteration

2023-10-17 Thread Michael S. Tsirkin
On Tue, Oct 17, 2023 at 05:32:34PM -0700, Si-Wei Liu wrote:
> 
> 
> On 10/6/2023 2:48 AM, Michael S. Tsirkin wrote:
> > On Fri, Oct 06, 2023 at 09:58:30AM +0100, Joao Martins wrote:
> > > On 03/10/2023 15:01, Michael S. Tsirkin wrote:
> > > > On Wed, Sep 27, 2023 at 12:14:28PM +0100, Joao Martins wrote:
> > > > > On setups with one or more virtio-net devices with vhost on,
> > > > > dirty tracking iteration increases cost the bigger the number
> > > > > amount of queues are set up e.g. on idle guests migration the
> > > > > following is observed with virtio-net with vhost=on:
> > > > > 
> > > > > 48 queues -> 78.11%  [.] vhost_dev_sync_region.isra.13
> > > > > 8 queues -> 40.50%   [.] vhost_dev_sync_region.isra.13
> > > > > 1 queue -> 6.89% [.] vhost_dev_sync_region.isra.13
> > > > > 2 devices, 1 queue -> 18.60%  [.] vhost_dev_sync_region.isra.14
> > > > > 
> > > > > With high memory rates the symptom is lack of convergence as soon
> > > > > as it has a vhost device with a sufficiently high number of queues,
> > > > > the sufficient number of vhost devices.
> > > > > 
> > > > > On every migration iteration (every 100msecs) it will redundantly
> > > > > query the *shared log* the number of queues configured with vhost
> > > > > that exist in the guest. For the virtqueue data, this is necessary,
> > > > > but not for the memory sections which are the same. So
> > > > > essentially we end up scanning the dirty log too often.
> > > > > 
> > > > > To fix that, select a vhost device responsible for scanning the
> > > > > log with regards to memory sections dirty tracking. It is selected
> > > > > when we enable the logger (during migration) and cleared when we
> > > > > disable the logger.
> > > > > 
> > > > > The real problem, however, is exactly that: a device per vhost 
> > > > > worker/qp,
> > > > > when there should be a device representing a netdev (for N vhost 
> > > > > workers).
> > > > > Given this problem exists for any Qemu these days, figured a simpler
> > > > > solution is better to increase stable tree's coverage; thus don't
> > > > > change the device model of sw vhost to fix this "over log scan" issue.
> > > > > 
> > > > > Signed-off-by: Joao Martins 
> > > > > ---
> > > > > I am not fully sure the heuristic captures the myriad of different 
> > > > > vhost
> > > > > devices -- I think so. IIUC, the log is always shared, it's just 
> > > > > whether
> > > > > it's qemu head memory or via /dev/shm when other processes want to
> > > > > access it.
> > > > Thanks for working on this.
> > > > 
> > > > I don't think this works like this because different types of different
> > > > vhost devices have different regions - see e.g. vhost_region_add_section
> > > > I am also not sure all devices are running at the same time - e.g.
> > > > some could be disconnected, and vhost_sync_dirty_bitmap takes this
> > > > into account.
> > > > 
> > > Good point. But this all means logic in selecting the 'logger' to take 
> > > into
> > > considering whether vhost_dev::log_enabled or vhost_dev::started right?
> > > 
> > > With respect to regions it seems like this can only change depending on 
> > > whether
> > > one of the vhost devices, backend_type is VHOST_BACKEND_TYPE_USER *and* 
> > > whether
> > > the backend sets vhost_backend_can_merge?
> > > 
> > > With respect to 'could be disconnected' during migration not devices can 
> > > be
> > > added or removed during migration, so might not be something that occurs 
> > > during
> > > migration.
> > > I placed this in log_sync exactly to just cover migration, unless
> > > there's some other way that disconnects the vhost and changes these 
> > > variables
> > > during migration.
> > The *frontend* can't be added or removed (ATM - this is just because we lack
> > good ways to describe devices that can be migrated, so all we
> > came up with is passing same command line on both sides,
> > and this breaks if you add/remove things in the process).
> > We really shouldn't bake this assumption into code if we can
> > help it though.
> > 
> > But I digress.
> > 
> > The *backend* can disconnect at any time as this is not guest visible.
> > 
> > > > But the idea is I think a good one - I just feel more refactoring is
> > > > needed.
> > > Can you expand on what refactoring you were thinking for this fix?
> > Better separate the idea of logging from device. then we can
> > have a single logger that collects data from devices to decide
> > what needs to be logged.
> Discussion. I think the troublemaker here is the vhost-user clients that
> attempt to round down to (huge) page boundary and then has to merge
> adjacent sections, leading to differing views between vhost devices. While I
> agree it is a great idea to separate logging from device, it isn't clear to
> me how that can help the case where there could be a mix of both vhost-user
> and vhost-kernel clients in the same qemu process, in which case it would
> need at least 2 separate vhost loggers for the specific 

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

2023-10-17 Thread LIU Zhiwei



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

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

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

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

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

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

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


Acked-by: LIU Zhiwei 

Zhiwei

  
  riscv_cpu_validate_priv_spec(cpu, _err);

  if (local_err != NULL) {




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

2023-10-17 Thread LIU Zhiwei

+CC Richard

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

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


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

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

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

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

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

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

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


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


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

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

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




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

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


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


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


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


Acked-by: LIU Zhiwei 

Zhiwei




Re: [PATCH] configure: define "pkg-config" in addition to "pkgconfig"

2023-10-17 Thread Thomas Huth

On 17/10/2023 17.36, Paolo Bonzini wrote:

Meson used to allow both "pkgconfig" and "pkg-config" entries in machine
files; the former was used for dependency lookup and the latter
was used as return value for "find_program('pkg-config')", which is a less
common use-case and one that QEMU does not need.

This inconsistency is going to be fixed by Meson 1.3, which will deprecate
"pkgconfig" in favor of "pkg-config" (the less common one, but it makes
sense because it matches the name of the binary). For backward
compatibility it is still allowed to define both, so do that in the
configure-generated machine file.

Related: https://github.com/mesonbuild/meson/pull/12385
Signed-off-by: Paolo Bonzini 
---
  configure | 1 +
  1 file changed, 1 insertion(+)

diff --git a/configure b/configure
index 8827a29bf4c..b4ea78c77d8 100755
--- a/configure
+++ b/configure
@@ -1736,6 +1736,7 @@ if test "$skip_meson" = no; then
echo "ar = [$(meson_quote $ar)]" >> $cross
echo "nm = [$(meson_quote $nm)]" >> $cross
echo "pkgconfig = [$(meson_quote $pkg_config)]" >> $cross
+  echo "pkg-config = [$(meson_quote $pkg_config)]" >> $cross
echo "ranlib = [$(meson_quote $ranlib)]" >> $cross
if has $sdl2_config; then
  echo "sdl2-config = [$(meson_quote $sdl2_config)]" >> $cross


Reviewed-by: Thomas Huth 




Re: [PATCH v3 0/4] qapi/migration: Dedup migration parameter objects and fix tls-authz crash

2023-10-17 Thread Markus Armbruster
Peter Xu  writes:

> On Tue, Oct 17, 2023 at 08:32:02AM +0200, Markus Armbruster wrote:
>> I can see two useful QAPI generator features:
>
> Agreed.
>
>> 
>> * Improved handling of missing member documentation
>> 
>>   Problem: many members lack documentation.  We silently generate
>>   documentation like
>> 
>>   name-of-member
>>   Not documented
>> 
>>   for them.
>> 
>>   Possible improvement: make missing member documentation a hard error,
>>   create a knob to suppress the error for a type.  Open question: how to
>>   best document member documentation is incomplete.
>
> @MigrationSetParameters should fall into this category.

Unless we can get rid of it.

> IMHO it's just wanted in some use case that we don't want to list member
> documentations, instead we want to show something else. In this case
> referring to documentation of another object (@MigrationParameters).

Yes.  A different example is QKeyCode.

>> * Suppress documentation for internal-only definitions
>> 
>>   Problem: generated documentation covers everything, even types that
>>   aren't visible in QMP.  The irrelevant material is distracting and
>>   possibly confusing for users, and may be bothersome to maintain for
>>   developers.
>> 
>>   Possible improvement: include only the types visible in QMP in
>>   documentation, similar to how we do for query-qmp-schema.  Open
>>   question: what level of documentation to require for internal-only
>>   types.
>
> @MigrationParameter should fall into this category.

Yes.

> IMHO we should treat them the same as any code written, for example, in C.
> We don't necessarily need to apply any rule on it, like we don't require
> comment for any line of code, but we prefer comments / documentations when
> necessary.  That (how much documentation needed for the code) is judged
> during code review, and can apply also to internally used QAPI definitions.

Makes sense, but even then tools to assist with spotting missing
documentation would be useful.  How to best do that is not obvious to
me.




Re: [PATCH] MAINTAINERS: Add hw/input/lasips2.c to the HPPA machine section

2023-10-17 Thread Philippe Mathieu-Daudé

On 17/10/23 17:19, Thomas Huth wrote:

hw/input/lasips2.c and the corresponding header include/hw/input/lasips2.h
are only used by the HPPA machine, so add them to the corresponding section
in the MAINTAINERS file.

Signed-off-by: Thomas Huth 
---
  MAINTAINERS | 2 ++
  1 file changed, 2 insertions(+)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH v2 1/2] tcg: Add tcg_gen_{ld,st}_i128

2023-10-17 Thread Philippe Mathieu-Daudé

On 18/10/23 03:19, gaosong wrote:

在 2023/10/14 上午1:51, Richard Henderson 写道:

Do not require the translators to jump through concat and
extract of i64 in order to move values to and from  env.

Signed-off-by: Richard Henderson 
---
  include/tcg/tcg-op-common.h |  3 +++
  tcg/tcg-op.c    | 22 ++
  2 files changed, 25 insertions(+)

Reviewed-by: Song Gao 


And per 
https://lore.kernel.org/qemu-devel/88015945-49f7-195b-7e78-08d9281d1...@loongson.cn/:


Tested-by: Song Gao 




Re: [PATCH] hw/audio/pcspk: Inline pcspk_init()

2023-10-17 Thread Philippe Mathieu-Daudé

On 17/10/23 22:08, Mark Cave-Ayland wrote:

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


pcspk_init() is a legacy init function, inline and remove it.

Signed-off-by: Philippe Mathieu-Daudé 
---
  include/hw/audio/pcspk.h | 10 --
  hw/i386/pc.c |  3 ++-
  hw/isa/i82378.c  |  5 -
  hw/mips/jazz.c   |  5 -
  4 files changed, 10 insertions(+), 13 deletions(-)




diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c
index c32d2b0b0a..aac851747c 100644
--- a/hw/mips/jazz.c
+++ b/hw/mips/jazz.c
@@ -177,6 +177,7 @@ static void mips_jazz_init(MachineState *machine,
  SysBusDevice *sysbus;
  ISABus *isa_bus;
  ISADevice *pit;
+    ISADevice *pcspk;
  DriveInfo *fds[MAX_FD];
  MemoryRegion *bios = g_new(MemoryRegion, 1);
  MemoryRegion *bios2 = g_new(MemoryRegion, 1);
@@ -279,7 +280,9 @@ static void mips_jazz_init(MachineState *machine,
  isa_bus_register_input_irqs(isa_bus, i8259);
  i8257_dma_init(isa_bus, 0);
  pit = i8254_pit_init(isa_bus, 0x40, 0, NULL);
-    pcspk_init(isa_new(TYPE_PC_SPEAKER), isa_bus, pit);
+    pcspk = isa_new(TYPE_PC_SPEAKER);
+    object_property_set_link(OBJECT(pcspk), "pit", OBJECT(pit), NULL);
+    isa_realize_and_unref(pcspk, isa_bus, _fatal);
  /* Video card */
  switch (jazz_model) {


Possibly you might want to pass errp instead of NULL for the last 
parameter of object_property_set_link() in i82378_realize()?


Oops you are right. I'll use _fatal.

But 
regardless:


Reviewed-by: Mark Cave-Ayland 


Thanks!




RE: [PATCH v2 3/3] target/hexagon: avoid shadowing globals

2023-10-17 Thread Brian Cain


> -Original Message-
> From: Philippe Mathieu-Daudé 
> Sent: Tuesday, October 10, 2023 12:23 AM
> To: Brian Cain ; richard.hender...@linaro.org;
> a...@rev.ng
> Cc: arm...@redhat.com; peter.mayd...@linaro.org; Matheus Bernardino
> (QUIC) ; stefa...@redhat.com; a...@rev.ng;
> Marco Liebel (QUIC) ; ltaylorsimp...@gmail.com;
> Thomas Huth ; Daniel P. Berrangé
> ; qemu-devel@nongnu.org
> Subject: Re: [PATCH v2 3/3] target/hexagon: avoid shadowing globals
> 
> WARNING: This email originated from outside of Qualcomm. Please be wary of
> any links or attachments, and do not enable macros.
> 
> On 9/10/23 22:53, Brian Cain wrote:
> >> On 9/10/23 08:09, Philippe Mathieu-Daudé wrote:
> >>> On 6/10/23 00:22, Brian Cain wrote:
>  The typedef `vaddr` is shadowed by `vaddr` identifiers, so we rename the
>  identifiers to avoid shadowing the type name.
> >>>
> >>> This one surprises me, since we have other occurences:
> >>>
> >>> include/exec/memory.h:751:bool memory_get_xlat_addr(IOMMUTLBEntry
> >>> *iotlb, void **vaddr,
> >>>   include/qemu/plugin.h:199:void qemu_plugin_vcpu_mem_cb(CPUState
> >>> *cpu, uint64_t vaddr,
> >>> target/arm/internals.h:643:G_NORETURN void
> >>> arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
> >>> target/i386/tcg/helper-tcg.h:70:G_NORETURN void
> >>> handle_unaligned_access(CPUX86State *env, vaddr vaddr,
> >>> ...
> >>>
> >>> $ git grep -w vaddr, | wc -l
> >>>207
> >>>
> >>> What is the error/warning like?
> >>
> >> OK I could reproduce, I suppose you are building with Clang which
> >> doesn't support shadow-local so you get global warnings too (as
> >> mentioned in this patch subject...):
> >
> > No -- I generally build with gcc and only double-check the clang results to
> make sure I don't see any new failures there.
> >
> > But I've not tested "-Wshadow" with clang yet.  I found these by adding "-
> Wshadow=global" to "-Wshadow=local".  I thought it might be useful to
> address these too while we're here.
> >
> >> In file included from ../../gdbstub/trace.h:1,
> >>from ../../gdbstub/softmmu.c:30:
> >> trace/trace-gdbstub.h: In function
> '_nocheck__trace_gdbstub_hit_watchpoint':
> >> trace/trace-gdbstub.h:903:106: error: declaration of 'vaddr' shadows a
> >> global declaration [-Werror=shadow]
> >> 903 | static inline void _nocheck__trace_gdbstub_hit_watchpoint(const
> >> char * type, int cpu_gdb_index, uint64_t vaddr)
> >> |
> >>   ~^
> >> In file included from include/sysemu/accel-ops.h:13,
> >>from include/sysemu/cpus.h:4,
> >>from ../../gdbstub/softmmu.c:21:
> >> include/exec/cpu-common.h:21:18: note: shadowed declaration is here
> >>  21 | typedef uint64_t vaddr;
> >> |  ^
> >> trace/trace-gdbstub.h: In function 'trace_gdbstub_hit_watchpoint':
> >> trace/trace-gdbstub.h:923:96: error: declaration of 'vaddr' shadows a
> >> global declaration [-Werror=shadow]
> >> 923 | static inline void trace_gdbstub_hit_watchpoint(const char *
> >> type, int cpu_gdb_index, uint64_t vaddr)
> >> |
> >> ~^
> >> include/exec/cpu-common.h:21:18: note: shadowed declaration is here
> >>  21 | typedef uint64_t vaddr;
> >> |  ^
> 
> If we have to clean that for -Wshadow=global, I'm tempted to rename
> the typedef as 'vaddr_t' and keep the 'vaddr' variable names.
> 
> Richard, Anton, what do you think?

Feels like I may have strolled into uncharted territory.  I'll just drop the 
patch that is intended to address -Wshadow=global and resurrect it if/when we 
decide to take that on in general.

> >> Clang users got confused by this, IIUC Markus and Thomas idea is
> >> to only enable these warnings for GCC, enforcing them for Clang
> >> users via CI (until Clang get this option supported). Personally
> >> I'd rather enable the warning once for all, waiting for Clang
> >> support (or clean/enable global shadowing for GCC too).
> >
> > Hopefully it's helpful or at least benign if we address the shadowed globals
> under target/hexagon/ for now, even if "-Wshadow=global" is not enabled.
> >
> >> See this thread:
> >> https://lore.kernel.org/qemu-devel/11abc551-188e-85c0-fe55-
> >> b2b58d351...@redhat.com/
> >>
> >> Regards,
> >>
> >> Phil.



Re: [PATCH v2 1/4] softmmu/physmem: Warn with ram_block_discard_range() on MAP_PRIVATE file mapping

2023-10-17 Thread Xiaoyao Li

David,

On 7/6/2023 3:56 PM, David Hildenbrand wrote:

ram_block_discard_range() cannot possibly do the right thing in
MAP_PRIVATE file mappings in the general case.

To achieve the documented semantics, we also have to punch a hole into
the file, possibly messing with other MAP_PRIVATE/MAP_SHARED mappings
of such a file.

For example, using VM templating -- see commit b17fbbe55cba ("migration:
allow private destination ram with x-ignore-shared") -- in combination with
any mechanism that relies on discarding of RAM is problematic. This
includes:
* Postcopy live migration
* virtio-balloon inflation/deflation or free-page-reporting
* virtio-mem

So at least warn that there is something possibly dangerous is going on
when using ram_block_discard_range() in these cases.

Acked-by: Peter Xu 
Tested-by: Mario Casquero 
Signed-off-by: David Hildenbrand 
---
  softmmu/physmem.c | 18 ++
  1 file changed, 18 insertions(+)

diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index bda475a719..4ee157bda4 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -3456,6 +3456,24 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t 
start, size_t length)
   * so a userfault will trigger.
   */
  #ifdef CONFIG_FALLOCATE_PUNCH_HOLE
+/*
+ * We'll discard data from the actual file, even though we only
+ * have a MAP_PRIVATE mapping, possibly messing with other
+ * MAP_PRIVATE/MAP_SHARED mappings. There is no easy way to
+ * change that behavior whithout violating the promised
+ * semantics of ram_block_discard_range().
+ *
+ * Only warn, because it work as long as nobody else uses that
+ * file.
+ */
+if (!qemu_ram_is_shared(rb)) {
+warn_report_once("ram_block_discard_range: Discarding RAM"
+ " in private file mappings is possibly"
+ " dangerous, because it will modify the"
+ " underlying file and will affect other"
+ " users of the file");
+}
+


TDX has two types of memory backend for each RAM, shared memory and 
private memory. Private memory is serviced by guest memfd and shared 
memory can also be backed with a fd.


At any time, only one type needs to be valid, which means the opposite 
can be discarded. We do implement the memory discard when TDX converts 
the memory[1]. It will trigger this warning 100% because by default the 
guest memfd is not mapped as shared (MAP_SHARED).


Simply remove the warning will fail the purpose of this patch. The other 
option is to skip the warning for TDX case, which looks vary hacky. Do 
you have any idea?


[1] 
https://lore.kernel.org/all/20230914035117.3285885-18-xiaoyao...@intel.com/



  ret = fallocate(rb->fd, FALLOC_FL_PUNCH_HOLE | 
FALLOC_FL_KEEP_SIZE,
  start, length);
  if (ret) {





[PATCH v2] contrib/plugins: Close file descriptor on error return

2023-10-17 Thread Cong Liu
This patch closes the file descriptor fd on error return to avoid
resource leak.

Fixes: ec7ee95db909 ("contrib/plugins: fix coverity warning in lockstep")
Signed-off-by: Cong Liu 
---
 contrib/plugins/lockstep.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/contrib/plugins/lockstep.c b/contrib/plugins/lockstep.c
index f0cb8792c6fa..237543b43a76 100644
--- a/contrib/plugins/lockstep.c
+++ b/contrib/plugins/lockstep.c
@@ -257,6 +257,7 @@ static bool setup_socket(const char *path)
 sockaddr.sun_family = AF_UNIX;
 if (g_strlcpy(sockaddr.sun_path, path, pathlen) >= pathlen) {
 perror("bad path");
+close(fd);
 return false;
 }
 
@@ -303,6 +304,7 @@ static bool connect_socket(const char *path)
 sockaddr.sun_family = AF_UNIX;
 if (g_strlcpy(sockaddr.sun_path, path, pathlen) >= pathlen) {
 perror("bad path");
+close(fd);
 return false;
 }
 
-- 
2.34.1




RE: [PATCH v2 02/27] vfio: Introduce base object for VFIOContainer and targetted interface

2023-10-17 Thread Duan, Zhenzhong
Hi Cédric,

>-Original Message-
>From: Cédric Le Goater 
>Sent: Tuesday, October 17, 2023 11:51 PM
>Subject: Re: [PATCH v2 02/27] vfio: Introduce base object for VFIOContainer and
>targetted interface
>
>On 10/16/23 10:31, Zhenzhong Duan wrote:
>> From: Eric Auger 
>>
>> Introduce a dumb VFIOContainer base object and its targetted interface.
>> This is willingly not a QOM object because we don't want it to be
>> visible from the user interface.  The VFIOContainer will be smoothly
>> populated in subsequent patches as well as interfaces.
>>
>> No fucntional change intended.
>>
>> Signed-off-by: Eric Auger 
>> Signed-off-by: Yi Liu 
>> Signed-off-by: Yi Sun 
>> Signed-off-by: Zhenzhong Duan 
>> ---
>>   include/hw/vfio/vfio-common.h |  8 +--
>>   include/hw/vfio/vfio-container-base.h | 82 +++
>>   2 files changed, 84 insertions(+), 6 deletions(-)
>>   create mode 100644 include/hw/vfio/vfio-container-base.h
>>
>> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
>> index 34648e518e..9651cf921c 100644
>> --- a/include/hw/vfio/vfio-common.h
>> +++ b/include/hw/vfio/vfio-common.h
>> @@ -30,6 +30,7 @@
>>   #include 
>>   #endif
>>   #include "sysemu/sysemu.h"
>> +#include "hw/vfio/vfio-container-base.h"
>>
>>   #define VFIO_MSG_PREFIX "vfio %s: "
>>
>> @@ -81,6 +82,7 @@ typedef struct VFIOAddressSpace {
>>   struct VFIOGroup;
>>
>>   typedef struct VFIOLegacyContainer {
>> +VFIOContainer bcontainer;
>
>That's the parent class, right ?

Right.

>
>>   VFIOAddressSpace *space;
>>   int fd; /* /dev/vfio/vfio, empowered by the attached groups */
>>   MemoryListener listener;
>> @@ -200,12 +202,6 @@ typedef struct VFIODisplay {
>>   } dmabuf;
>>   } VFIODisplay;
>>
>> -typedef struct {
>> -unsigned long *bitmap;
>> -hwaddr size;
>> -hwaddr pages;
>> -} VFIOBitmap;
>> -
>>   void vfio_host_win_add(VFIOLegacyContainer *container,
>>  hwaddr min_iova, hwaddr max_iova,
>>  uint64_t iova_pgsizes);
>> diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-
>container-base.h
>> new file mode 100644
>> index 00..afc8543d22
>> --- /dev/null
>> +++ b/include/hw/vfio/vfio-container-base.h
>> @@ -0,0 +1,82 @@
>> +/*
>> + * VFIO BASE CONTAINER
>> + *
>> + * Copyright (C) 2023 Intel Corporation.
>> + * Copyright Red Hat, Inc. 2023
>> + *
>> + * Authors: Yi Liu 
>> + *  Eric Auger 
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> +
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> +
>> + * You should have received a copy of the GNU General Public License along
>> + * with this program; if not, see .
>> + */
>> +
>> +#ifndef HW_VFIO_VFIO_BASE_CONTAINER_H
>> +#define HW_VFIO_VFIO_BASE_CONTAINER_H
>> +
>> +#include "exec/memory.h"
>> +#ifndef CONFIG_USER_ONLY
>> +#include "exec/hwaddr.h"
>> +#endif
>> +
>> +typedef struct VFIOContainer VFIOContainer;
>> +typedef struct VFIODevice VFIODevice;
>> +typedef struct VFIOIOMMUBackendOpsClass VFIOIOMMUBackendOpsClass;
>> +
>> +typedef struct {
>> +unsigned long *bitmap;
>> +hwaddr size;
>> +hwaddr pages;
>> +} VFIOBitmap;
>> +
>> +/*
>> + * This is the base object for vfio container backends
>> + */
>> +struct VFIOContainer {
>> +VFIOIOMMUBackendOpsClass *ops;
>
>This is unexpected.
>
>I thought that an abstract QOM model for VFIOContainer was going
>to be introduced with a VFIOContainerClass with the ops below
>(VFIOIOMMUBackendOpsClass).
>
>Then, we would call :
>
>VFIOContainerClass *vcc = VFIO_CONTAINER_GET_CLASS(container);
>
>to get the specific implementation for the current container.
>
>I don't understand the VFIOIOMMUBackendOpsClass pointer and
>TYPE_VFIO_IOMMU_BACKEND_OPS. It seems redundant.

The original implementation was abstract QOM model. But it wasn't accepted,
see https://lore.kernel.org/all/YmuFv2s5TPuw7K%2Fu@yekko/ for details.

Thanks
Zhenzhong


RE: [PATCH v2 01/27] vfio: Rename VFIOContainer into VFIOLegacyContainer

2023-10-17 Thread Duan, Zhenzhong


>-Original Message-
>From: Cédric Le Goater 
>Sent: Tuesday, October 17, 2023 11:51 PM
>Subject: Re: [PATCH v2 01/27] vfio: Rename VFIOContainer into
>VFIOLegacyContainer
>
>Hello,
>
>On 10/16/23 10:31, Zhenzhong Duan wrote:
>> From: Eric Auger 
>>
>> In the prospect to introduce a base object for the VFIOContainer
>> and derive into the existing legacy container and the iommufd
>> based container, let's rename the existing one into
>> VFIOLegacyContainer. This is just an incremental step to ease
>> the migration. Soon there won't be any reference to the legacy
>> container in the common.c code. Only the container.c should
>> handle the VFIOLegacyContainer object.
>
>So I think I would have kept the current name as it is, named the
>new abtract QOM object VFIOContainerBase and then, derived from
>VFIOContainerBase, the current implementation VFIOContainer and
>the new one VFIOContainerIOMMUFD.

OK, will do.

Thanks
Zhenzhong


Re: [PATCH 18/18] target/i386: remove gen_op

2023-10-17 Thread Richard Henderson

On 10/14/23 03:01, Paolo Bonzini wrote:

It is not used anymore by the old decoder, inline the CMP case into CMPS and 
SCAS.

Signed-off-by: Paolo Bonzini 
---
  target/i386/tcg/translate.c | 145 +++-
  1 file changed, 12 insertions(+), 133 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 09/18] target/i386: do not clobber A0 in POP translation

2023-10-17 Thread Richard Henderson

On 10/14/23 03:01, Paolo Bonzini wrote:

The new decoder likes to compute the address in A0 very early, so the
gen_lea_v_seg in gen_pop_T0 would clobber the address of the memory
operand.  Instead use T0 since it is already available and will be
overwritten immediately after.

Signed-off-by: Paolo Bonzini 
---
  target/i386/tcg/translate.c | 34 --
  1 file changed, 20 insertions(+), 14 deletions(-)



Reviewed-by: Richard Henderson 

r~



Re: [PATCH 06/18] target/i386: accept full MemOp in gen_ext_tl

2023-10-17 Thread Richard Henderson

On 10/14/23 03:01, Paolo Bonzini wrote:

Use MO_SIGN to indicate signed vs. unsigned extension, and filter out
bits other than MO_SIGN and MO_SIZE.

Signed-off-by: Paolo Bonzini 
---
  target/i386/tcg/translate.c | 30 +++---
  1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 4f6f9fa7e52..d7d6c85877d 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -699,18 +699,18 @@ static inline void gen_op_movl_T0_Dshift(DisasContext *s, 
MemOp ot)
  tcg_gen_shli_tl(s->T0, s->T0, ot);
  };
  
-static TCGv gen_ext_tl(TCGv dst, TCGv src, MemOp size, bool sign)

+static TCGv gen_ext_tl(TCGv dst, TCGv src, MemOp ot)
  {
-switch (size) {
+switch (ot & MO_SIZE) {
  case MO_8:
-if (sign) {
+if (ot & MO_SIGN) {
  tcg_gen_ext8s_tl(dst, src);
  } else {
  tcg_gen_ext8u_tl(dst, src);
  }
  return dst;
  case MO_16:
-if (sign) {
+if (ot & MO_SIGN) {
  tcg_gen_ext16s_tl(dst, src);
  } else {
  tcg_gen_ext16u_tl(dst, src);


A reminder yet again that I should make this generic -- we've several copies in the code 
base...


Reviewed-by: Richard Henderson 


r~



Re: [PATCH 04/18] tests/tcg/i386: initialize more registers in test-avx

2023-10-17 Thread Richard Henderson

On 10/14/23 03:01, Paolo Bonzini wrote:

Some instructions use YMM0 implicitly, or use YMM9 as a read-modify-write
register destination.  Initialize those registers as well.

Signed-off-by: Paolo Bonzini 


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 02/18] target/i386: validate VEX.W for AVX instructions

2023-10-17 Thread Richard Henderson

On 10/14/23 03:01, Paolo Bonzini wrote:

Instructions in VEX exception class 6 generally look at the value of
VEX.W.  Note that the manual places some instructions incorrectly in
class 4, for example VPERMQ which has no non-VEX encoding and no legacy
SSE analogue.  AMD does a mess of its own, as documented in the comment
that this patch adds.

Most of them are checked for VEX.W=0, and are listed in the manual
(though with an omission) in table 2-16; VPERMQ and VPERMPD check for
VEX.W=1, which is only listed in the instruction description.  Others,
such as VPSRLV, VPSLLV and the FMA3 instructions, use VEX.W to switch
between a 32-bit and 64-bit operation.

Fix more of the class 4/class 6 mismatches, and implement the check for
VEX.W in TCG.

Signed-off-by: Paolo Bonzini 
---
  target/i386/tcg/decode-new.c.inc | 133 +--
  target/i386/tcg/decode-new.h |   6 ++
  2 files changed, 99 insertions(+), 40 deletions(-)

diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 790339eaf25..850271e0898 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -43,6 +43,47 @@
   * There are a couple cases in which instructions (e.g. MOVD) write the
   * whole XMM or MM register but are established incorrectly in the manual
   * as "d" or "q".  These have to be fixed for the decoder to work correctly.
+ *
+ * Speaking about imprecisions in the manual, the decoder treats all
+ * exception-class 4 instructions as having an optional VEX prefix, and
+ * all exception-class 6 instructions as having a mandatory VEX prefix.
+ * This is true except for a dozen instructions; these are in exception
+ * class 4 but do not ignore the VEX.W bit (which does not even exist
+ * without a VEX prefix).  These instructions are mostly listed in Intel's
+ * table 2-16, but with a few exceptions.
+ *
+ * The AMD manual has more precise subclasses for exceptions, and unlike Intel
+ * they list the VEX.W requirements in the exception classes as well (except
+ * when they don't).  AMD describes class 6 as "AVX Mixed Memory Argument"
+ * without defining what a mixed memory argument is, but still use 4 as the
+ * primary exception class... except when they don't.
+ *
+ * The summary is:
+ *   Intel AMD VEX.W   note
+ * ---
+ * vpblendd  4 4J  0
+ * vpblendvb 4 4E-X0   (*)
+ * vpbroadcastq  6 6D  0   (+)
+ * vpermd/vpermps4 4H  0   (§)
+ * vpermq/vpermpd4 4H-11   (§)
+ * vpermilpd/vpermilps   4 6E  0   (^)
+ * vpmaskmovd6 4K  significant (^)
+ * vpsllv4 4K  significant
+ * vpsrav4 4J  0
+ * vpsrlv4 4K  significant
+ * vtestps/vtestpd   4 4G  0
+ *
+ *(*)  AMD lists VPBLENDVB as related to SSE4.1 PBLENDVB, which may
+ * explain why it is considered exception class 4.  However,
+ * Intel says that VEX-only instructions should be in class 6...
+ *
+ *(+)  Not found in Intel's table 2-16
+ *
+ *(§)  4H and 4H-1 do not mention VEX.W requirements, which are
+ * however present in the description of the instruction
+ *
+ *(^)  these are the two cases in which Intel and AMD disagree on the
+ * primary exception class


Oof.

Acked-by: Richard Henderson 


r~



Re: [PATCH 01/18] target/i386: group common checks in the decoding phase

2023-10-17 Thread Richard Henderson

On 10/14/23 03:01, Paolo Bonzini wrote:

@@ -224,6 +233,8 @@ struct X86OpEntry {
  unsigned vex_class:8;
  X86VEXSpecial vex_special:8;
  uint16_t valid_prefix:16;
+uint8_t  check:8;
+uint8_t  intercept:8;
  bool is_decode:1;
  };


Unless you have a good reason otherwise, use "unsigned" with bit fields. In this case, 
'uint8_t' is really 'unsigned char', and so gdb will print the ascii by defailt.


Otherwise,
Reviewed-by: Richard Henderson 


r~



Re: [PATCH v2 1/2] tcg: Add tcg_gen_{ld,st}_i128

2023-10-17 Thread gaosong

在 2023/10/14 上午1:51, Richard Henderson 写道:

Do not require the translators to jump through concat and
extract of i64 in order to move values to and from  env.

Signed-off-by: Richard Henderson 
---
  include/tcg/tcg-op-common.h |  3 +++
  tcg/tcg-op.c| 22 ++
  2 files changed, 25 insertions(+)

Reviewed-by: Song Gao 

Thanks.
Song Gao

diff --git a/include/tcg/tcg-op-common.h b/include/tcg/tcg-op-common.h
index 2048f92b5e..56d4e9cb9f 100644
--- a/include/tcg/tcg-op-common.h
+++ b/include/tcg/tcg-op-common.h
@@ -747,6 +747,9 @@ void tcg_gen_mov_i128(TCGv_i128 dst, TCGv_i128 src);
  void tcg_gen_extr_i128_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i128 arg);
  void tcg_gen_concat_i64_i128(TCGv_i128 ret, TCGv_i64 lo, TCGv_i64 hi);
  
+void tcg_gen_ld_i128(TCGv_i128 ret, TCGv_ptr base, tcg_target_long offset);

+void tcg_gen_st_i128(TCGv_i128 val, TCGv_ptr base, tcg_target_long offset);
+
  static inline void tcg_gen_concat32_i64(TCGv_i64 ret, TCGv_i64 lo, TCGv_i64 
hi)
  {
  tcg_gen_deposit_i64(ret, lo, hi, 32, 32);
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 393dbcd01c..12bcedf42f 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -2880,6 +2880,28 @@ void tcg_gen_mov_i128(TCGv_i128 dst, TCGv_i128 src)
  }
  }
  
+void tcg_gen_ld_i128(TCGv_i128 ret, TCGv_ptr base, tcg_target_long offset)

+{
+if (HOST_BIG_ENDIAN) {
+tcg_gen_ld_i64(TCGV128_HIGH(ret), base, offset);
+tcg_gen_ld_i64(TCGV128_LOW(ret), base, offset + 8);
+} else {
+tcg_gen_ld_i64(TCGV128_LOW(ret), base, offset);
+tcg_gen_ld_i64(TCGV128_HIGH(ret), base, offset + 8);
+}
+}
+
+void tcg_gen_st_i128(TCGv_i128 val, TCGv_ptr base, tcg_target_long offset)
+{
+if (HOST_BIG_ENDIAN) {
+tcg_gen_st_i64(TCGV128_HIGH(val), base, offset);
+tcg_gen_st_i64(TCGV128_LOW(val), base, offset + 8);
+} else {
+tcg_gen_st_i64(TCGV128_LOW(val), base, offset);
+tcg_gen_st_i64(TCGV128_HIGH(val), base, offset + 8);
+}
+}
+
  /* QEMU specific operations.  */
  
  void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx)





Re: [RFC PATCH 0/2] target/loongarch: Use i128 for 128-bit loads/stores

2023-10-17 Thread gaosong

在 2023/10/17 下午8:38, Philippe Mathieu-Daudé 写道:

RFC because unsure and untested...

Based-on: <20231013175109.124308-1-richard.hender...@linaro.org>
   tcg: Add tcg_gen_{ld,st}_i128

Philippe Mathieu-Daudé (2):
   target/loongarch: Use i128 for 128-bit load/store in VST[X]/XVST
   target/loongarch: Use i128 for 128-bit load/store in XVLD

  target/loongarch/translate.c| 12 ++
  target/loongarch/insn_trans/trans_vec.c.inc | 46 +++--
  2 files changed, 28 insertions(+), 30 deletions(-)



I had tested it,  you can drop the 'RFC' title.

Tested-by: Song Gao 

Thanks.
Song Gao




Re: [PATCH] vhost: Perform memory section dirty scans once per iteration

2023-10-17 Thread Si-Wei Liu




On 10/6/2023 2:48 AM, Michael S. Tsirkin wrote:

On Fri, Oct 06, 2023 at 09:58:30AM +0100, Joao Martins wrote:

On 03/10/2023 15:01, Michael S. Tsirkin wrote:

On Wed, Sep 27, 2023 at 12:14:28PM +0100, Joao Martins wrote:

On setups with one or more virtio-net devices with vhost on,
dirty tracking iteration increases cost the bigger the number
amount of queues are set up e.g. on idle guests migration the
following is observed with virtio-net with vhost=on:

48 queues -> 78.11%  [.] vhost_dev_sync_region.isra.13
8 queues -> 40.50%   [.] vhost_dev_sync_region.isra.13
1 queue -> 6.89% [.] vhost_dev_sync_region.isra.13
2 devices, 1 queue -> 18.60%  [.] vhost_dev_sync_region.isra.14

With high memory rates the symptom is lack of convergence as soon
as it has a vhost device with a sufficiently high number of queues,
the sufficient number of vhost devices.

On every migration iteration (every 100msecs) it will redundantly
query the *shared log* the number of queues configured with vhost
that exist in the guest. For the virtqueue data, this is necessary,
but not for the memory sections which are the same. So
essentially we end up scanning the dirty log too often.

To fix that, select a vhost device responsible for scanning the
log with regards to memory sections dirty tracking. It is selected
when we enable the logger (during migration) and cleared when we
disable the logger.

The real problem, however, is exactly that: a device per vhost worker/qp,
when there should be a device representing a netdev (for N vhost workers).
Given this problem exists for any Qemu these days, figured a simpler
solution is better to increase stable tree's coverage; thus don't
change the device model of sw vhost to fix this "over log scan" issue.

Signed-off-by: Joao Martins 
---
I am not fully sure the heuristic captures the myriad of different vhost
devices -- I think so. IIUC, the log is always shared, it's just whether
it's qemu head memory or via /dev/shm when other processes want to
access it.

Thanks for working on this.

I don't think this works like this because different types of different
vhost devices have different regions - see e.g. vhost_region_add_section
I am also not sure all devices are running at the same time - e.g.
some could be disconnected, and vhost_sync_dirty_bitmap takes this
into account.


Good point. But this all means logic in selecting the 'logger' to take into
considering whether vhost_dev::log_enabled or vhost_dev::started right?

With respect to regions it seems like this can only change depending on whether
one of the vhost devices, backend_type is VHOST_BACKEND_TYPE_USER *and* whether
the backend sets vhost_backend_can_merge?

With respect to 'could be disconnected' during migration not devices can be
added or removed during migration, so might not be something that occurs during
migration.
I placed this in log_sync exactly to just cover migration, unless
there's some other way that disconnects the vhost and changes these variables
during migration.

The *frontend* can't be added or removed (ATM - this is just because we lack
good ways to describe devices that can be migrated, so all we
came up with is passing same command line on both sides,
and this breaks if you add/remove things in the process).
We really shouldn't bake this assumption into code if we can
help it though.

But I digress.

The *backend* can disconnect at any time as this is not guest visible.


But the idea is I think a good one - I just feel more refactoring is
needed.

Can you expand on what refactoring you were thinking for this fix?

Better separate the idea of logging from device. then we can
have a single logger that collects data from devices to decide
what needs to be logged.
Discussion. I think the troublemaker here is the vhost-user clients that 
attempt to round down to (huge) page boundary and then has to merge 
adjacent sections, leading to differing views between vhost devices. 
While I agree it is a great idea to separate logging from device, it 
isn't clear to me how that can help the case where there could be a mix 
of both vhost-user and vhost-kernel clients in the same qemu process, in 
which case it would need at least 2 separate vhost loggers for the 
specific vhost type? Or you would think there's value to unify the two 
distinct subsystems with one single vhost logger facility? Noted the 
vhost logging interface (vhost kernel or vhost userspace) doesn't 
support the notion of separate logging of memory buffer sections against 
those for VQs, all QEMU can rely on is various sections in the memory 
table and basically a single dirty bitmap for both guest buffers and VQs 
are indistinctively shared by all vhost devices. How does it help to 
just refactor QEMU part of code using today's vhost backend interface, I 
am not sure.


Regardless, IMHO for fixing stable p.o.v it might be less risky and 
valuable to just limit the fix to vhost-kernel case (to be more precise, 
non-vhost-user type and without 

Re: [PATCH v3 11/11] tests/qtest: Adding PCS Module test to GMAC Qtest

2023-10-17 Thread Hao Wu
On Tue, Oct 17, 2023 at 4:04 PM Nabih Estefan 
wrote:

> From: Nabih Estefan Diaz 
>
>  - Add PCS Register check to npcm_gmac-test
>
> Signed-off-by: Nabih Estefan Diaz 
>
Reviewed-by: Hao Wu 

> ---
>  tests/qtest/npcm_gmac-test.c | 134 ++-
>  1 file changed, 133 insertions(+), 1 deletion(-)
>
> diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
> index 84511fd915..1f0ad664f4 100644
> --- a/tests/qtest/npcm_gmac-test.c
> +++ b/tests/qtest/npcm_gmac-test.c
> @@ -20,6 +20,10 @@
>  /* Name of the GMAC Device */
>  #define TYPE_NPCM_GMAC "npcm-gmac"
>
> +/* Address of the PCS Module */
> +#define PCS_BASE_ADDRESS 0xf078
> +#define NPCM_PCS_IND_AC_BA 0x1fe
> +
>  typedef struct GMACModule {
>  int irq;
>  uint64_t base_addr;
> @@ -111,6 +115,62 @@ typedef enum NPCMRegister {
>  NPCM_GMAC_PTP_STNSUR = 0x714,
>  NPCM_GMAC_PTP_TAR = 0x718,
>  NPCM_GMAC_PTP_TTSR = 0x71c,
> +
> +/* PCS Registers */
> +NPCM_PCS_SR_CTL_ID1 = 0x3c0008,
> +NPCM_PCS_SR_CTL_ID2 = 0x3c000a,
> +NPCM_PCS_SR_CTL_STS = 0x3c0010,
> +
> +NPCM_PCS_SR_MII_CTRL = 0x3e,
> +NPCM_PCS_SR_MII_STS = 0x3e0002,
> +NPCM_PCS_SR_MII_DEV_ID1 = 0x3e0004,
> +NPCM_PCS_SR_MII_DEV_ID2 = 0x3e0006,
> +NPCM_PCS_SR_MII_AN_ADV = 0x3e0008,
> +NPCM_PCS_SR_MII_LP_BABL = 0x3e000a,
> +NPCM_PCS_SR_MII_AN_EXPN = 0x3e000c,
> +NPCM_PCS_SR_MII_EXT_STS = 0x3e001e,
> +
> +NPCM_PCS_SR_TIM_SYNC_ABL = 0x3e0e10,
> +NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR = 0x3e0e12,
> +NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR = 0x3e0e14,
> +NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR = 0x3e0e16,
> +NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR = 0x3e0e18,
> +NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR = 0x3e0e1a,
> +NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR = 0x3e0e1c,
> +NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR = 0x3e0e1e,
> +NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR = 0x3e0e20,
> +
> +NPCM_PCS_VR_MII_MMD_DIG_CTRL1 = 0x3f,
> +NPCM_PCS_VR_MII_AN_CTRL = 0x3f0002,
> +NPCM_PCS_VR_MII_AN_INTR_STS = 0x3f0004,
> +NPCM_PCS_VR_MII_TC = 0x3f0006,
> +NPCM_PCS_VR_MII_DBG_CTRL = 0x3f000a,
> +NPCM_PCS_VR_MII_EEE_MCTRL0 = 0x3f000c,
> +NPCM_PCS_VR_MII_EEE_TXTIMER = 0x3f0010,
> +NPCM_PCS_VR_MII_EEE_RXTIMER = 0x3f0012,
> +NPCM_PCS_VR_MII_LINK_TIMER_CTRL = 0x3f0014,
> +NPCM_PCS_VR_MII_EEE_MCTRL1 = 0x3f0016,
> +NPCM_PCS_VR_MII_DIG_STS = 0x3f0020,
> +NPCM_PCS_VR_MII_ICG_ERRCNT1 = 0x3f0022,
> +NPCM_PCS_VR_MII_MISC_STS = 0x3f0030,
> +NPCM_PCS_VR_MII_RX_LSTS = 0x3f0040,
> +NPCM_PCS_VR_MII_MP_TX_BSTCTRL0 = 0x3f0070,
> +NPCM_PCS_VR_MII_MP_TX_LVLCTRL0 = 0x3f0074,
> +NPCM_PCS_VR_MII_MP_TX_GENCTRL0 = 0x3f007a,
> +NPCM_PCS_VR_MII_MP_TX_GENCTRL1 = 0x3f007c,
> +NPCM_PCS_VR_MII_MP_TX_STS = 0x3f0090,
> +NPCM_PCS_VR_MII_MP_RX_GENCTRL0 = 0x3f00b0,
> +NPCM_PCS_VR_MII_MP_RX_GENCTRL1 = 0x3f00b2,
> +NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0 = 0x3f00ba,
> +NPCM_PCS_VR_MII_MP_MPLL_CTRL0 = 0x3f00f0,
> +NPCM_PCS_VR_MII_MP_MPLL_CTRL1 = 0x3f00f2,
> +NPCM_PCS_VR_MII_MP_MPLL_STS = 0x3f0110,
> +NPCM_PCS_VR_MII_MP_MISC_CTRL2 = 0x3f0126,
> +NPCM_PCS_VR_MII_MP_LVL_CTRL = 0x3f0130,
> +NPCM_PCS_VR_MII_MP_MISC_CTRL0 = 0x3f0132,
> +NPCM_PCS_VR_MII_MP_MISC_CTRL1 = 0x3f0134,
> +NPCM_PCS_VR_MII_DIG_CTRL2 = 0x3f01c2,
> +NPCM_PCS_VR_MII_DIG_ERRCNT_SEL = 0x3f01c4,
>  } NPCMRegister;
>
>  static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
> @@ -119,6 +179,15 @@ static uint32_t gmac_read(QTestState *qts, const
> GMACModule *mod,
>  return qtest_readl(qts, mod->base_addr + regno);
>  }
>
> +static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
> +  NPCMRegister regno)
> +{
> +uint32_t write_value = (regno & 0x3ffe00) >> 9;
> +qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
> +uint32_t read_offset = regno & 0x1ff;
> +return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
> +}
> +
>  /* Check that GMAC registers are reset to default value */
>  static void test_init(gconstpointer test_data)
>  {
> @@ -129,7 +198,12 @@ static void test_init(gconstpointer test_data)
>  #define CHECK_REG32(regno, value) \
>  do { \
>  g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
> -} while (0)
> +} while (0) ;
> +
> +#define CHECK_REG_PCS(regno, value) \
> +do { \
> +g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
> +} while (0) ;
>
>  CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
>  CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
> @@ -180,6 +254,64 @@ static void test_init(gconstpointer test_data)
>  CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
>  CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
>
> +/* TODO Add registers PCS */
> +if (mod->base_addr == 0xf0802000) {
> +CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID1, 0x699e)
> +CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID2, 0)
> +

Re: [PATCH v3 09/11] hw/net: GMAC Rx Implementation

2023-10-17 Thread Hao Wu
Please consolidate the commit message in this patch. I think we only need
to describe the functionality you implemented here (i.e. the receive (RX)
for the GMAC model) and how you did it. There's no need to keep the verbose
comment on each corner cases we had.



On Tue, Oct 17, 2023 at 4:04 PM Nabih Estefan 
wrote:

> From: Nabih Estefan Diaz 
>
> - Implementation of Receive function for packets
> - Implementation for reading and writing from and to descriptors in
>   memory for Rx
>
> NOTE: At this point in development we believe this function is working
> as intended, and the kernel supports these findings, but we need the
> Transmit function to work before we upload
>
> Signed-off-by: Nabih Estefan Diaz 
>
> hw/net: npcm_gmac Flush queued packets when starting RX
>
> When RX starts, we need to flush the queued packets so that they
> can be received by the GMAC device. Without this it won't work
> with TAP NIC device.
>
> Signed-off-by: Hao Wu 
>
> hw/net: Handle RX desc full in NPCM GMAC
>
> When RX descriptor list is full, it returns a DMA_STATUS for software to
> handle it. But there's no way to indicate the software ha handled all RX
> descriptors and the whole pipeline stalls.
>
> We do something similar to NPCM7XX EMC to handle this case.
>
> 1. Return packet size when RX descriptor is full, effectively dropping
> these packets in such a case.
> 2. When software clears RX descriptor full bit, continue receiving further
> packets by flushing QEMU packet queue.
>
> Signed-off-by: Hao Wu 
>
> hw/net: Receive and drop packets when descriptors are full in GMAC
>
> Effectively this allows QEMU to receive and drop incoming packets when
> RX descriptors are full. Similar to EMC, this lets GMAC to drop packets
> faster, especially during bootup sequence.
>
> Signed-off-by: Hao Wu 
>
> hw/net: Update frame_ptr during gmac_receive
>
> There was a bug that frame_ptr wasn't updated after receiving
> the first batch of data, causing the received data to be wrong
> when the frame is too large.
>
> Signed-off-by: Hao Wu 
>
> hw/net: Fix GMAC not detecting owned by software properly in RX
>
> RX should stop receiving when a descriptor is owned by software
> but currently implementation made it reversed (owned by DMA) instead.
>
> Signed-off-by: Hao Wu 
>
> hw/net: Fix GMAC receive problem
>
> Fix the following 2 problems in GMAC receive function:
>
> 1. When kernel driver disables GMAC RX interrupt and all descriptors
> are full, it will not send further interrupt to the kernel
> driver as the driver doesn't listen to NPCM_DMA_STATUS_RU.
> Since descriptors full indicates that there are packets received
> we should also set NPCM_DMA_STATUS_RI for firing the interrupt.
> 2. Kernel driver does not clear rdes0 from used descriptor so we need
> to clear it such that old flags are removed before setting new
> flags.
>
> Signed-off-by: Hao Wu 
> ---
>  hw/net/npcm_gmac.c | 356 ++---
>  include/hw/net/npcm_gmac.h |  28 +--
>  2 files changed, 342 insertions(+), 42 deletions(-)
>
> diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c
> index 6f8109e0ee..a7c8b67223 100644
> --- a/hw/net/npcm_gmac.c
> +++ b/hw/net/npcm_gmac.c
> @@ -23,7 +23,11 @@
>  #include "hw/registerfields.h"
>  #include "hw/net/mii.h"
>  #include "hw/net/npcm_gmac.h"
> +#include "linux/if_ether.h"
>  #include "migration/vmstate.h"
> +#include "net/checksum.h"
> +#include "net/net.h"
> +#include "qemu/cutils.h"
>  #include "qemu/log.h"
>  #include "qemu/units.h"
>  #include "sysemu/dma.h"
> @@ -91,7 +95,6 @@ REG32(NPCM_GMAC_PTP_TTSR, 0x71c)
>  #define NPCM_DMA_BUS_MODE_SWR   BIT(0)
>
>  static const uint32_t npcm_gmac_cold_reset_values[NPCM_GMAC_NR_REGS] = {
> -/* Reduce version to 3.2 so that the kernel can enable interrupt. */
>
Why is this line removed?

>  [R_NPCM_GMAC_VERSION] = 0x1032,
>  [R_NPCM_GMAC_TIMER_CTRL]  = 0x03e8,
>  [R_NPCM_GMAC_MAC0_ADDR_HI]= 0x8000,
> @@ -146,6 +149,17 @@ static void gmac_phy_set_link(NPCMGMACState *s, bool
> active)
>
>  static bool gmac_can_receive(NetClientState *nc)
>  {
> +NPCMGMACState *gmac = NPCM_GMAC(qemu_get_nic_opaque(nc));
> +
> +/* If GMAC receive is disabled. */
> +if (!(gmac->regs[R_NPCM_GMAC_MAC_CONFIG] &
> NPCM_GMAC_MAC_CONFIG_RX_EN)) {
> +return false;
> +}
> +
> +/* If GMAC DMA RX is stopped. */
> +if (!(gmac->regs[R_NPCM_DMA_CONTROL] &
> NPCM_DMA_CONTROL_START_STOP_RX)) {
> +return false;
> +}
>  return true;
>  }
>
> @@ -191,11 +205,288 @@ static void gmac_update_irq(NPCMGMACState *gmac)
>  qemu_set_irq(gmac->irq, level);
>  }
>
> -static ssize_t gmac_receive(NetClientState *nc, const uint8_t *buf,
> size_t len)
> +static int gmac_read_rx_desc(dma_addr_t addr, struct NPCMGMACRxDesc *desc)
>  {
> -/* Placeholder */
> +if (dma_memory_read(_space_memory, addr, desc,
> +sizeof(*desc), 

Re: [PATCH v3 08/11] hw/net: General GMAC Implementation

2023-10-17 Thread Hao Wu
On Tue, Oct 17, 2023 at 4:04 PM Nabih Estefan 
wrote:

> From: Nabih Estefan Diaz 
>
> - General GMAC Register handling
> - GMAC IRQ Handling
> - Added traces in some methods for debugging
> - Lots of declarations for accessing information on GMAC Descriptors
> (npcm_gmac.h file)
>
> NOTE: With code on this state, the GMAC can boot-up properly and will show
> up in the ifconfig command on the BMC
>
> Google-Rebase-Count: 1
> Signed-off-by: Nabih Estefan Diaz 
> Google-Bug-Id: 237557100
> Change-Id: I3a4332ee5bab31b919782031a77c5b943f45ca2f
>
Please remove the Google-specific hashes. (Only signed-off-by is needed.)

> ---
>  include/hw/net/npcm_gmac.h | 198 ++---
>  1 file changed, 184 insertions(+), 14 deletions(-)
>
> diff --git a/include/hw/net/npcm_gmac.h b/include/hw/net/npcm_gmac.h
> index e5729e83ea..c97eb6fe6e 100644
> --- a/include/hw/net/npcm_gmac.h
> +++ b/include/hw/net/npcm_gmac.h
> @@ -34,13 +34,15 @@ struct NPCMGMACRxDesc {
>  };
>
>  /* NPCMGMACRxDesc.flags values */
> -/* RDES2 and RDES3 are buffer address pointers */
> -/* Owner: 0 = software, 1 = gmac */
> -#define RX_DESC_RDES0_OWNER_MASK BIT(31)
> +/* RDES2 and RDES3 are buffer addresses */
> +/* Owner: 0 = software, 1 = dma */
> +#define RX_DESC_RDES0_OWN BIT(31)
>  /* Destination Address Filter Fail */
> -#define RX_DESC_RDES0_DEST_ADDR_FILT_FAIL_MASK BIT(30)
> -/* Frame length*/
> -#define RX_DESC_RDES0_FRAME_LEN_MASK(word) extract32(word, 16, 29)
> +#define RX_DESC_RDES0_DEST_ADDR_FILT_FAIL BIT(30)
> +/* Frame length */
> +#define RX_DESC_RDES0_FRAME_LEN_MASK(word) extract32(word, 16, 14)
> +/* Frame length Shift*/
> +#define RX_DESC_RDES0_FRAME_LEN_SHIFT 16
>  /* Error Summary */
>  #define RX_DESC_RDES0_ERR_SUMM_MASK BIT(15)
>  /* Descriptor Error */
> @@ -83,9 +85,9 @@ struct NPCMGMACRxDesc {
>  /* Receive Buffer 2 Size */
>  #define RX_DESC_RDES1_BFFR2_SZ_SHIFT 11
>  #define RX_DESC_RDES1_BFFR2_SZ_MASK(word) extract32(word, \
> -RX_DESC_RDES1_BFFR2_SZ_SHIFT, 10 + RX_DESC_RDES1_BFFR2_SZ_SHIFT)
> +RX_DESC_RDES1_BFFR2_SZ_SHIFT, 11)
>  /* Receive Buffer 1 Size */
> -#define RX_DESC_RDES1_BFFR1_SZ_MASK(word) extract32(word, 0, 10)
> +#define RX_DESC_RDES1_BFFR1_SZ_MASK(word) extract32(word, 0, 11)
>
>
>  struct NPCMGMACTxDesc {
> @@ -96,9 +98,9 @@ struct NPCMGMACTxDesc {
>  };
>
>  /* NPCMGMACTxDesc.flags values */
> -/* TDES2 and TDES3 are buffer address pointers */
> +/* TDES2 and TDES3 are buffer addresses */
>  /* Owner: 0 = software, 1 = gmac */
> -#define TX_DESC_TDES0_OWNER_MASK BIT(31)
> +#define TX_DESC_TDES0_OWN BIT(31)
>  /* Tx Time Stamp Status */
>  #define TX_DESC_TDES0_TTSS_MASK BIT(17)
>  /* IP Header Error */
> @@ -122,7 +124,7 @@ struct NPCMGMACTxDesc {
>  /* VLAN Frame */
>  #define TX_DESC_TDES0_VLAN_FRM_MASK BIT(7)
>  /* Collision Count */
> -#define TX_DESC_TDES0_COLL_CNT_MASK(word) extract32(word, 3, 6)
> +#define TX_DESC_TDES0_COLL_CNT_MASK(word) extract32(word, 3, 4)
>  /* Excessive Deferral */
>  #define TX_DESC_TDES0_EXCS_DEF_MASK BIT(2)
>  /* Underflow Error */
> @@ -137,7 +139,7 @@ struct NPCMGMACTxDesc {
>  /* Last Segment */
>  #define TX_DESC_TDES1_FIRST_SEG_MASK BIT(29)
>  /* Checksum Insertion Control */
> -#define TX_DESC_TDES1_CHKSM_INS_CTRL_MASK(word) extract32(word, 27, 28)
> +#define TX_DESC_TDES1_CHKSM_INS_CTRL_MASK(word) extract32(word, 27, 2)
>  /* Disable Cyclic Redundancy Check */
>  #define TX_DESC_TDES1_DIS_CDC_MASK BIT(26)
>  /* Transmit End of Ring */
> @@ -145,9 +147,9 @@ struct NPCMGMACTxDesc {
>  /* Secondary Address Chained */
>  #define TX_DESC_TDES1_SEC_ADDR_CHND_MASK BIT(24)
>  /* Transmit Buffer 2 Size */
> -#define TX_DESC_TDES1_BFFR2_SZ_MASK(word) extract32(word, 11, 21)
> +#define TX_DESC_TDES1_BFFR2_SZ_MASK(word) extract32(word, 11, 11)
>  /* Transmit Buffer 1 Size */
> -#define TX_DESC_TDES1_BFFR1_SZ_MASK(word) extract32(word, 0, 10)
> +#define TX_DESC_TDES1_BFFR1_SZ_MASK(word) extract32(word, 0, 11)
>
>  typedef struct NPCMGMACState {
>  SysBusDevice parent;
> @@ -165,4 +167,172 @@ typedef struct NPCMGMACState {
>  #define TYPE_NPCM_GMAC "npcm-gmac"
>  OBJECT_DECLARE_SIMPLE_TYPE(NPCMGMACState, NPCM_GMAC)
>
> +/* Mask for RO bits in Status */
> +#define NPCM_DMA_STATUS_RO_MASK(word) (word & 0xfffe)
> +/* Mask for RO bits in Status */
> +#define NPCM_DMA_STATUS_W1C_MASK(word) (word & 0x1e7ff)
> +
> +/* Transmit Process State */
> +#define NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT 20
> +/* Transmit States */
> +#define NPCM_DMA_STATUS_TX_STOPPED_STATE \
> +(0b000 << NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT)
> +#define NPCM_DMA_STATUS_TX_RUNNING_FETCHING_STATE \
> +(0b001 << NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT)
> +#define NPCM_DMA_STATUS_TX_RUNNING_WAITING_STATE \
> +(0b010 << NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT)
> +#define NPCM_DMA_STATUS_TX_RUNNING_READ_STATE \
> +(0b011 << NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT)
> +#define NPCM_DMA_STATUS_TX_SUSPENDED_STATE \
> +(0b110 << 

Re: [PATCH v3 07/11] include/hw/net: Implemented Classes and Masks for GMAC Descriptors

2023-10-17 Thread Hao Wu
On Tue, Oct 17, 2023 at 4:04 PM Nabih Estefan 
wrote:

> From: Nabih Estefan Diaz 
>
>  - Implemeted classes for GMAC Receive and Transmit Descriptors
>  - Implemented Masks for said descriptors
>
> Signed-off-by: Nabih Estefan Diaz 
>
Reviewed-by: Hao Wu 

> ---
>  hw/net/npcm_gmac.c   | 183 +++
>  hw/net/trace-events  |   9 ++
>  include/hw/net/npcm_gmac.h   |   2 -
>  tests/qtest/npcm_gmac-test.c |   2 +-
>  4 files changed, 150 insertions(+), 46 deletions(-)
>
> diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c
> index 5ce632858d..6f8109e0ee 100644
> --- a/hw/net/npcm_gmac.c
> +++ b/hw/net/npcm_gmac.c
> @@ -32,7 +32,7 @@
>  REG32(NPCM_DMA_BUS_MODE, 0x1000)
>  REG32(NPCM_DMA_XMT_POLL_DEMAND, 0x1004)
>  REG32(NPCM_DMA_RCV_POLL_DEMAND, 0x1008)
> -REG32(NPCM_DMA_RCV_BASE_ADDR, 0x100c)
> +REG32(NPCM_DMA_RX_BASE_ADDR, 0x100c)
>  REG32(NPCM_DMA_TX_BASE_ADDR, 0x1010)
>  REG32(NPCM_DMA_STATUS, 0x1014)
>  REG32(NPCM_DMA_CONTROL, 0x1018)
> @@ -91,7 +91,8 @@ REG32(NPCM_GMAC_PTP_TTSR, 0x71c)
>  #define NPCM_DMA_BUS_MODE_SWR   BIT(0)
>
>  static const uint32_t npcm_gmac_cold_reset_values[NPCM_GMAC_NR_REGS] = {
> -[R_NPCM_GMAC_VERSION] = 0x1037,
> +/* Reduce version to 3.2 so that the kernel can enable interrupt. */
> +[R_NPCM_GMAC_VERSION] = 0x1032,
>  [R_NPCM_GMAC_TIMER_CTRL]  = 0x03e8,
>  [R_NPCM_GMAC_MAC0_ADDR_HI]= 0x8000,
>  [R_NPCM_GMAC_MAC0_ADDR_LO]= 0x,
> @@ -125,12 +126,12 @@ static const uint16_t phy_reg_init[] = {
>  [MII_EXTSTAT]   = 0x3000, /* 1000BASTE_T full-duplex capable */
>  };
>
> -static void npcm_gmac_soft_reset(NPCMGMACState *s)
> +static void npcm_gmac_soft_reset(NPCMGMACState *gmac)
>  {
> -memcpy(s->regs, npcm_gmac_cold_reset_values,
> +memcpy(gmac->regs, npcm_gmac_cold_reset_values,
> NPCM_GMAC_NR_REGS * sizeof(uint32_t));
>  /* Clear reset bits */
> -s->regs[R_NPCM_DMA_BUS_MODE] &= ~NPCM_DMA_BUS_MODE_SWR;
> +gmac->regs[R_NPCM_DMA_BUS_MODE] &= ~NPCM_DMA_BUS_MODE_SWR;
>  }
>
>  static void gmac_phy_set_link(NPCMGMACState *s, bool active)
> @@ -148,11 +149,53 @@ static bool gmac_can_receive(NetClientState *nc)
>  return true;
>  }
>
> -static ssize_t gmac_receive(NetClientState *nc, const uint8_t *buf,
> size_t len1)
> +/*
> + * Function that updates the GMAC IRQ
> + * It find the logical OR of the enabled bits for NIS (if enabled)
> + * It find the logical OR of the enabled bits for AIS (if enabled)
> + */
> +static void gmac_update_irq(NPCMGMACState *gmac)
>  {
> -return 0;
> +/*
> + * Check if the normal interrupts summery is enabled
> + * if so, add the bits for the summary that are enabled
> + */
> +if (gmac->regs[R_NPCM_DMA_INTR_ENA] & gmac->regs[R_NPCM_DMA_STATUS] &
> +(NPCM_DMA_INTR_ENAB_NIE_BITS))
> +{
> +gmac->regs[R_NPCM_DMA_STATUS] |=  NPCM_DMA_STATUS_NIS;
> +}
> +/*
> + * Check if the abnormal interrupts summery is enabled
> + * if so, add the bits for the summary that are enabled
> + */
> +if (gmac->regs[R_NPCM_DMA_INTR_ENA] & gmac->regs[R_NPCM_DMA_STATUS] &
> +(NPCM_DMA_INTR_ENAB_AIE_BITS))
> +{
> +gmac->regs[R_NPCM_DMA_STATUS] |=  NPCM_DMA_STATUS_AIS;
> +}
> +
> +/* Get the logical OR of both normal and abnormal interrupts */
> +int level = !!((gmac->regs[R_NPCM_DMA_STATUS] &
> +gmac->regs[R_NPCM_DMA_INTR_ENA] &
> +NPCM_DMA_STATUS_NIS) |
> +   (gmac->regs[R_NPCM_DMA_STATUS] &
> +   gmac->regs[R_NPCM_DMA_INTR_ENA] &
> +   NPCM_DMA_STATUS_AIS));
> +
> +/* Set the IRQ */
> +trace_npcm_gmac_update_irq(DEVICE(gmac)->canonical_path,
> +   gmac->regs[R_NPCM_DMA_STATUS],
> +   gmac->regs[R_NPCM_DMA_INTR_ENA],
> +   level);
> +qemu_set_irq(gmac->irq, level);
>  }
>
> +static ssize_t gmac_receive(NetClientState *nc, const uint8_t *buf,
> size_t len)
> +{
> +/* Placeholder */
> +return 0;
> +}
>  static void gmac_cleanup(NetClientState *nc)
>  {
>  /* Nothing to do yet. */
> @@ -166,7 +209,7 @@ static void gmac_set_link(NetClientState *nc)
>  gmac_phy_set_link(s, !nc->link_down);
>  }
>
> -static void npcm_gmac_mdio_access(NPCMGMACState *s, uint16_t v)
> +static void npcm_gmac_mdio_access(NPCMGMACState *gmac, uint16_t v)
>  {
>  bool busy = v & NPCM_GMAC_MII_ADDR_BUSY;
>  uint8_t is_write;
> @@ -183,33 +226,38 @@ static void npcm_gmac_mdio_access(NPCMGMACState *s,
> uint16_t v)
>
>
>  if (v & NPCM_GMAC_MII_ADDR_WRITE) {
> -data = s->regs[R_NPCM_GMAC_MII_DATA];
> +data = gmac->regs[R_NPCM_GMAC_MII_DATA];
>  /* Clear reset bit for BMCR register */
>  switch (gr) {
>  case MII_BMCR:
>  data &= ~MII_BMCR_RESET;
> -

Re: [PATCH v3 06/11] \tests/qtest: Creating qtest for GMAC Module

2023-10-17 Thread Hao Wu
You have an extra "\" in the title.

On Tue, Oct 17, 2023 at 4:04 PM Nabih Estefan 
wrote:

> From: Nabih Estefan Diaz 
>
>  - Created qtest to check initialization of registers in GMAC Module.
>  - Implemented test into Build File.
>
> Signed-off-by: Nabih Estefan Diaz 
> ---
>  tests/qtest/meson.build  |  11 +-
>  tests/qtest/npcm_gmac-test.c | 209 +++
>  2 files changed, 215 insertions(+), 5 deletions(-)
>  create mode 100644 tests/qtest/npcm_gmac-test.c
>
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index 05d26e9292..3ff9f5d364 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -191,6 +191,8 @@ qtests_npcm7xx = \
> 'npcm7xx_timer-test',
> 'npcm7xx_watchdog_timer-test'] + \
> (slirp.found() ? ['npcm7xx_emc-test'] : [])
> +qtests_npcm8xx = \
> +  ['npcm_gmac-test']
>
I haven't sent 8xx code yet (which I should do, sorry!). Maybe we should
remove 8xx related config for now?

>  qtests_aspeed = \
>['aspeed_hace-test',
> 'aspeed_smc-test',
> @@ -205,9 +207,7 @@ qtests_arm = \
>(config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed : [])
> + \
>(config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
>(config_all_devices.has_key('CONFIG_GENERIC_LOADER') ?
> ['hexloader-test'] : []) + \
> -  (config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ?
> ['tpm-tis-i2c-test'] : []) + \
> -  (config_all_devices.has_key('CONFIG_VEXPRESS') ? ['test-arm-mptimer'] :
> []) + \
> -  (config_all_devices.has_key('CONFIG_MICROBIT') ? ['microbit-test'] :
> []) + \
> +  (config_all_devices.has_key('CONFIG_NPCM8XX') ? qtests_npcm8xx : []) + \
>
ditto.

>['arm-cpu-features',
> 'boot-serial-test']
>
> @@ -219,8 +219,9 @@ qtests_aarch64 = \
>(config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ?
> ['xlnx-can-test', 'fuzz-xlnx-dp-test'] : []) + \
>(config_all_devices.has_key('CONFIG_XLNX_VERSAL') ? ['xlnx-canfd-test']
> : []) + \
>(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] :
> []) +  \
> -  (config_all.has_key('CONFIG_TCG') and
>   \
> -   config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ?
> ['tpm-tis-i2c-test'] : []) + \
> +  (config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed : [])
> + \
> +  (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
> +  (config_all_devices.has_key('CONFIG_NPCM8XX') ? qtests_npcm8xx : []) + \
>
ditto

>['arm-cpu-features',
> 'numa-test',
> 'boot-serial-test',
> diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
> new file mode 100644
> index 00..30d27e8dcc
> --- /dev/null
> +++ b/tests/qtest/npcm_gmac-test.c
> @@ -0,0 +1,209 @@
> +/*
> + * QTests for Nuvoton NPCM7xx/8xx GMAC Modules.
> + *
> + * Copyright 2022 Google LLC
>
nit: could be 2023 right now?

> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful, but
> WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
> + * for more details.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "libqos/libqos.h"
> +
> +/* Name of the GMAC Device */
> +#define TYPE_NPCM_GMAC "npcm-gmac"
> +
> +typedef struct GMACModule {
> +int irq;
> +uint64_t base_addr;
> +} GMACModule;
> +
> +typedef struct TestData {
> +const GMACModule *module;
> +} TestData;
> +
> +/* Values extracted from hw/arm/npcm8xx.c */
>
I think 7xx and 8xx has the same config for GMAC. Maybe use 7xx for now?

> +static const GMACModule gmac_module_list[] = {
> +{
> +.irq= 14,
> +.base_addr  = 0xf0802000
> +},
> +{
> +.irq= 15,
> +.base_addr  = 0xf0804000
> +},
> +{
> +.irq= 16,
> +.base_addr  = 0xf0806000
> +},
> +{
> +.irq= 17,
> +.base_addr  = 0xf0808000
> +}
> +};
> +
> +/* Returns the index of the GMAC module. */
> +static int gmac_module_index(const GMACModule *mod)
> +{
> +ptrdiff_t diff = mod - gmac_module_list;
> +
> +g_assert_true(diff >= 0 && diff < ARRAY_SIZE(gmac_module_list));
> +
> +return diff;
> +}
> +
> +/* 32-bit register indices. Taken from npcm_gmac.c */
> +typedef enum NPCMRegister {
> +/* DMA Registers */
> +NPCM_DMA_BUS_MODE = 0x1000,
> +NPCM_DMA_XMT_POLL_DEMAND = 0x1004,
> +NPCM_DMA_RCV_POLL_DEMAND = 0x1008,
> +NPCM_DMA_RCV_BASE_ADDR = 0x100c,
> +NPCM_DMA_TX_BASE_ADDR = 0x1010,
> +NPCM_DMA_STATUS = 0x1014,
> +NPCM_DMA_CONTROL = 0x1018,
> +NPCM_DMA_INTR_ENA = 0x101c,
> +NPCM_DMA_MISSED_FRAME_CTR = 0x1020,
> +NPCM_DMA_HOST_TX_DESC = 

RE: [PATCH] ui/gtk: full-screening all detached windows

2023-10-17 Thread Kim, Dongwon
Hi Marc-André,

> Hi
> 
> On Fri, Oct 13, 2023 at 2:51 AM Dongwon Kim 
> wrote:
> >
> > When turning on or off full-screen menu, all detached windows should
> > be full-screened or un-full-screened altogether.
> 
> I am not convinced this is desirable. Not only having multiple fullscreen 
> windows
> on the same screen is usually a bit harder to deal with. You typically want 
> one
> imho.
> 
> But the most annoying thing is probably that detached windows/consoles do not
> have the same shortcuts as the main window, and you can't unfullscreen them
> then...
> 
> Wouldn't you prefer to have a working fullscreen keyboard shortcut for
> detached tabs instead? This way, each window can be toggled full/unfull
> individually.

[DW] That is right. Two detached windows on the same display would be 
overlapped, which will be ugly. I also thought about that as well as other 
undesirable situations but my initial thought was the full-screen
menu is global and all QEMU windows should be controlled by it. Anyhow, I like 
your idea about individual control.. so we would probably need to add more 
full-screen menus, like 'fullscreen1, fullscreen2, fullscreen3..."
to the menu then also assign a hotkey to each one of them? 

> 
> thanks
> 
> >
> > Cc: Marc-André Lureau 
> > Signed-off-by: Dongwon Kim 
> > ---
> >  ui/gtk.c | 44 ++--
> >  1 file changed, 34 insertions(+), 10 deletions(-)
> >
> > diff --git a/ui/gtk.c b/ui/gtk.c
> > index 935de1209b..3a380f8d59 100644
> > --- a/ui/gtk.c
> > +++ b/ui/gtk.c
> > @@ -1452,29 +1452,53 @@ static void gd_accel_show_menubar(void
> > *opaque)  static void gd_menu_full_screen(GtkMenuItem *item, void
> > *opaque)  {
> >  GtkDisplayState *s = opaque;
> > -VirtualConsole *vc = gd_vc_find_current(s);
> > +VirtualConsole *vc;
> > +int i;
> >
> >  if (!s->full_screen) {
> >  gtk_notebook_set_show_tabs(GTK_NOTEBOOK(s->notebook), FALSE);
> >  gtk_widget_hide(s->menu_bar);
> > -if (vc->type == GD_VC_GFX) {
> > -gtk_widget_set_size_request(vc->gfx.drawing_area, -1, -1);
> > -}
> > -gtk_window_fullscreen(GTK_WINDOW(s->window));
> >  s->full_screen = TRUE;
> > +gtk_window_fullscreen(GTK_WINDOW(s->window));
> > +
> > +for (i = 0; i < s->nb_vcs; i++) {
> > +vc = >vc[i];
> > +if (!vc->window) {
> > +continue;
> > +}
> > +if (vc->type == GD_VC_GFX) {
> > +gtk_widget_set_size_request(vc->gfx.drawing_area, -1, -1);
> > +}
> > +gtk_window_fullscreen(GTK_WINDOW(vc->window));
> > +}
> >  } else {
> >  gtk_window_unfullscreen(GTK_WINDOW(s->window));
> > +
> > +for (i = 0; i < s->nb_vcs; i++) {
> > +vc = >vc[i];
> > +if (!vc->window) {
> > +continue;
> > +}
> > +gtk_window_unfullscreen(GTK_WINDOW(vc->window));
> > +
> > +if (vc->type == GD_VC_GFX) {
> > +vc->gfx.scale_x = 1.0;
> > +vc->gfx.scale_y = 1.0;
> > +gd_update_windowsize(vc);
> > +}
> > +}
> > +
> >  gd_menu_show_tabs(GTK_MENU_ITEM(s->show_tabs_item), s);
> >  if (gtk_check_menu_item_get_active(
> >  GTK_CHECK_MENU_ITEM(s->show_menubar_item))) {
> >  gtk_widget_show(s->menu_bar);
> >  }
> >  s->full_screen = FALSE;
> > -if (vc->type == GD_VC_GFX) {
> > -vc->gfx.scale_x = 1.0;
> > -vc->gfx.scale_y = 1.0;
> > -gd_update_windowsize(vc);
> > -}
> > +}
> > +
> > +vc = gd_vc_find_current(s);
> > +if (!vc) {
> > +return;
> >  }
> >
> >  gd_update_cursor(vc);
> > --
> > 2.20.1
> >



[PATCH v3 02/11] hw/arm: Add PCI mailbox module to Nuvoton SoC

2023-10-17 Thread Nabih Estefan
From: Hao Wu 

This patch wires the PCI mailbox module to Nuvoton SoC.

Google-Rebase-Count: 5
Google-Bug-Id: 262938292
Signed-off-by: Hao Wu 
Change-Id: Ifd858a7ed760557faa15a7a1cef66b2056f06e2e
---
 docs/system/arm/nuvoton.rst | 2 ++
 hw/arm/npcm7xx.c| 3 ++-
 include/hw/arm/npcm7xx.h| 1 +
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index 0424cae4b0..e611099545 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -50,6 +50,8 @@ Supported devices
  * Ethernet controller (EMC)
  * Tachometer
  * Peripheral SPI controller (PSPI)
+ * BIOS POST code FIFO
+ * PCI Mailbox
 
 Missing devices
 ---
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index c69e936669..c9e87162cb 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -86,7 +86,6 @@ enum NPCM7xxInterrupt {
 NPCM7XX_UART1_IRQ,
 NPCM7XX_UART2_IRQ,
 NPCM7XX_UART3_IRQ,
-NPCM7XX_PECI_IRQ= 6,
 NPCM7XX_PCI_MBOX_IRQ= 8,
 NPCM7XX_KCS_HIB_IRQ = 9,
 NPCM7XX_GMAC1_IRQ   = 14,
@@ -463,6 +462,8 @@ static void npcm7xx_init(Object *obj)
 object_initialize_child(obj, "pspi[*]", >pspi[i], TYPE_NPCM_PSPI);
 }
 
+object_initialize_child(obj, "pci-mbox", >pci_mbox,
+TYPE_NPCM7XX_PCI_MBOX);
 object_initialize_child(obj, "mmc", >mmc, TYPE_NPCM7XX_SDHCI);
 }
 
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index 273090ac60..cec3792a2e 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -105,6 +105,7 @@ struct NPCM7xxState {
 OHCISysBusState ohci;
 NPCM7xxFIUState fiu[2];
 NPCM7xxEMCState emc[2];
+NPCM7xxPCIMBoxState pci_mbox;
 NPCM7xxSDHCIState   mmc;
 NPCMPSPIState   pspi[2];
 };
-- 
2.42.0.655.g421f12c284-goog




[PATCH v3 08/11] hw/net: General GMAC Implementation

2023-10-17 Thread Nabih Estefan
From: Nabih Estefan Diaz 

- General GMAC Register handling
- GMAC IRQ Handling
- Added traces in some methods for debugging
- Lots of declarations for accessing information on GMAC Descriptors 
(npcm_gmac.h file)

NOTE: With code on this state, the GMAC can boot-up properly and will show up 
in the ifconfig command on the BMC

Google-Rebase-Count: 1
Signed-off-by: Nabih Estefan Diaz 
Google-Bug-Id: 237557100
Change-Id: I3a4332ee5bab31b919782031a77c5b943f45ca2f
---
 include/hw/net/npcm_gmac.h | 198 ++---
 1 file changed, 184 insertions(+), 14 deletions(-)

diff --git a/include/hw/net/npcm_gmac.h b/include/hw/net/npcm_gmac.h
index e5729e83ea..c97eb6fe6e 100644
--- a/include/hw/net/npcm_gmac.h
+++ b/include/hw/net/npcm_gmac.h
@@ -34,13 +34,15 @@ struct NPCMGMACRxDesc {
 };
 
 /* NPCMGMACRxDesc.flags values */
-/* RDES2 and RDES3 are buffer address pointers */
-/* Owner: 0 = software, 1 = gmac */
-#define RX_DESC_RDES0_OWNER_MASK BIT(31)
+/* RDES2 and RDES3 are buffer addresses */
+/* Owner: 0 = software, 1 = dma */
+#define RX_DESC_RDES0_OWN BIT(31)
 /* Destination Address Filter Fail */
-#define RX_DESC_RDES0_DEST_ADDR_FILT_FAIL_MASK BIT(30)
-/* Frame length*/
-#define RX_DESC_RDES0_FRAME_LEN_MASK(word) extract32(word, 16, 29)
+#define RX_DESC_RDES0_DEST_ADDR_FILT_FAIL BIT(30)
+/* Frame length */
+#define RX_DESC_RDES0_FRAME_LEN_MASK(word) extract32(word, 16, 14)
+/* Frame length Shift*/
+#define RX_DESC_RDES0_FRAME_LEN_SHIFT 16
 /* Error Summary */
 #define RX_DESC_RDES0_ERR_SUMM_MASK BIT(15)
 /* Descriptor Error */
@@ -83,9 +85,9 @@ struct NPCMGMACRxDesc {
 /* Receive Buffer 2 Size */
 #define RX_DESC_RDES1_BFFR2_SZ_SHIFT 11
 #define RX_DESC_RDES1_BFFR2_SZ_MASK(word) extract32(word, \
-RX_DESC_RDES1_BFFR2_SZ_SHIFT, 10 + RX_DESC_RDES1_BFFR2_SZ_SHIFT)
+RX_DESC_RDES1_BFFR2_SZ_SHIFT, 11)
 /* Receive Buffer 1 Size */
-#define RX_DESC_RDES1_BFFR1_SZ_MASK(word) extract32(word, 0, 10)
+#define RX_DESC_RDES1_BFFR1_SZ_MASK(word) extract32(word, 0, 11)
 
 
 struct NPCMGMACTxDesc {
@@ -96,9 +98,9 @@ struct NPCMGMACTxDesc {
 };
 
 /* NPCMGMACTxDesc.flags values */
-/* TDES2 and TDES3 are buffer address pointers */
+/* TDES2 and TDES3 are buffer addresses */
 /* Owner: 0 = software, 1 = gmac */
-#define TX_DESC_TDES0_OWNER_MASK BIT(31)
+#define TX_DESC_TDES0_OWN BIT(31)
 /* Tx Time Stamp Status */
 #define TX_DESC_TDES0_TTSS_MASK BIT(17)
 /* IP Header Error */
@@ -122,7 +124,7 @@ struct NPCMGMACTxDesc {
 /* VLAN Frame */
 #define TX_DESC_TDES0_VLAN_FRM_MASK BIT(7)
 /* Collision Count */
-#define TX_DESC_TDES0_COLL_CNT_MASK(word) extract32(word, 3, 6)
+#define TX_DESC_TDES0_COLL_CNT_MASK(word) extract32(word, 3, 4)
 /* Excessive Deferral */
 #define TX_DESC_TDES0_EXCS_DEF_MASK BIT(2)
 /* Underflow Error */
@@ -137,7 +139,7 @@ struct NPCMGMACTxDesc {
 /* Last Segment */
 #define TX_DESC_TDES1_FIRST_SEG_MASK BIT(29)
 /* Checksum Insertion Control */
-#define TX_DESC_TDES1_CHKSM_INS_CTRL_MASK(word) extract32(word, 27, 28)
+#define TX_DESC_TDES1_CHKSM_INS_CTRL_MASK(word) extract32(word, 27, 2)
 /* Disable Cyclic Redundancy Check */
 #define TX_DESC_TDES1_DIS_CDC_MASK BIT(26)
 /* Transmit End of Ring */
@@ -145,9 +147,9 @@ struct NPCMGMACTxDesc {
 /* Secondary Address Chained */
 #define TX_DESC_TDES1_SEC_ADDR_CHND_MASK BIT(24)
 /* Transmit Buffer 2 Size */
-#define TX_DESC_TDES1_BFFR2_SZ_MASK(word) extract32(word, 11, 21)
+#define TX_DESC_TDES1_BFFR2_SZ_MASK(word) extract32(word, 11, 11)
 /* Transmit Buffer 1 Size */
-#define TX_DESC_TDES1_BFFR1_SZ_MASK(word) extract32(word, 0, 10)
+#define TX_DESC_TDES1_BFFR1_SZ_MASK(word) extract32(word, 0, 11)
 
 typedef struct NPCMGMACState {
 SysBusDevice parent;
@@ -165,4 +167,172 @@ typedef struct NPCMGMACState {
 #define TYPE_NPCM_GMAC "npcm-gmac"
 OBJECT_DECLARE_SIMPLE_TYPE(NPCMGMACState, NPCM_GMAC)
 
+/* Mask for RO bits in Status */
+#define NPCM_DMA_STATUS_RO_MASK(word) (word & 0xfffe)
+/* Mask for RO bits in Status */
+#define NPCM_DMA_STATUS_W1C_MASK(word) (word & 0x1e7ff)
+
+/* Transmit Process State */
+#define NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT 20
+/* Transmit States */
+#define NPCM_DMA_STATUS_TX_STOPPED_STATE \
+(0b000 << NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT)
+#define NPCM_DMA_STATUS_TX_RUNNING_FETCHING_STATE \
+(0b001 << NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT)
+#define NPCM_DMA_STATUS_TX_RUNNING_WAITING_STATE \
+(0b010 << NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT)
+#define NPCM_DMA_STATUS_TX_RUNNING_READ_STATE \
+(0b011 << NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT)
+#define NPCM_DMA_STATUS_TX_SUSPENDED_STATE \
+(0b110 << NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT)
+#define NPCM_DMA_STATUS_TX_RUNNING_CLOSING_STATE \
+(0b111 << NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT)
+/* Transmit Process State */
+#define NPCM_DMA_STATUS_RX_PROCESS_STATE_SHIFT 17
+/* Receive States */
+#define NPCM_DMA_STATUS_RX_STOPPED_STATE \
+(0b000 << NPCM_DMA_STATUS_RX_PROCESS_STATE_SHIFT)
+#define 

[PATCH v3 05/11] hw/arm: Add GMAC devices to NPCM7XX SoC

2023-10-17 Thread Nabih Estefan
From: Hao Wu 

Signed-off-by: Hao Wu 
---
 hw/arm/npcm7xx.c | 36 ++--
 include/hw/arm/npcm7xx.h |  2 ++
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index c9e87162cb..12e11250e1 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -91,6 +91,7 @@ enum NPCM7xxInterrupt {
 NPCM7XX_GMAC1_IRQ   = 14,
 NPCM7XX_EMC1RX_IRQ  = 15,
 NPCM7XX_EMC1TX_IRQ,
+NPCM7XX_GMAC2_IRQ,
 NPCM7XX_MMC_IRQ = 26,
 NPCM7XX_PSPI2_IRQ   = 28,
 NPCM7XX_PSPI1_IRQ   = 31,
@@ -234,6 +235,12 @@ static const hwaddr npcm7xx_pspi_addr[] = {
 0xf0201000,
 };
 
+/* Register base address for each GMAC Module */
+static const hwaddr npcm7xx_gmac_addr[] = {
+0xf0802000,
+0xf0804000,
+};
+
 static const struct {
 hwaddr regs_addr;
 uint32_t unconnected_pins;
@@ -462,6 +469,10 @@ static void npcm7xx_init(Object *obj)
 object_initialize_child(obj, "pspi[*]", >pspi[i], TYPE_NPCM_PSPI);
 }
 
+for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
+object_initialize_child(obj, "gmac[*]", >gmac[i], TYPE_NPCM_GMAC);
+}
+
 object_initialize_child(obj, "pci-mbox", >pci_mbox,
 TYPE_NPCM7XX_PCI_MBOX);
 object_initialize_child(obj, "mmc", >mmc, TYPE_NPCM7XX_SDHCI);
@@ -695,6 +706,29 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 sysbus_connect_irq(sbd, 1, npcm7xx_irq(s, rx_irq));
 }
 
+/*
+ * GMAC Modules. Cannot fail.
+ */
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_gmac_addr) != ARRAY_SIZE(s->gmac));
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->gmac) != 2);
+for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
+SysBusDevice *sbd = SYS_BUS_DEVICE(>gmac[i]);
+
+/*
+ * The device exists regardless of whether it's connected to a QEMU
+ * netdev backend. So always instantiate it even if there is no
+ * backend.
+ */
+sysbus_realize(sbd, _abort);
+sysbus_mmio_map(sbd, 0, npcm7xx_gmac_addr[i]);
+int irq = i == 0 ? NPCM7XX_GMAC1_IRQ : NPCM7XX_GMAC2_IRQ;
+/*
+ * N.B. The values for the second argument sysbus_connect_irq are
+ * chosen to match the registration order in npcm7xx_emc_realize.
+ */
+sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, irq));
+}
+
 /*
  * Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
  * specified, but this is a programming error.
@@ -765,8 +799,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.siox[2]",  0xf0102000,   4 * KiB);
 create_unimplemented_device("npcm7xx.ahbpci",   0xf040,   1 * MiB);
 create_unimplemented_device("npcm7xx.mcphy",0xf05f,  64 * KiB);
-create_unimplemented_device("npcm7xx.gmac1",0xf0802000,   8 * KiB);
-create_unimplemented_device("npcm7xx.gmac2",0xf0804000,   8 * KiB);
 create_unimplemented_device("npcm7xx.vcd",  0xf081,  64 * KiB);
 create_unimplemented_device("npcm7xx.ece",  0xf082,   8 * KiB);
 create_unimplemented_device("npcm7xx.vdma", 0xf0822000,   8 * KiB);
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index cec3792a2e..9e5cf639a2 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -30,6 +30,7 @@
 #include "hw/misc/npcm7xx_pwm.h"
 #include "hw/misc/npcm7xx_rng.h"
 #include "hw/net/npcm7xx_emc.h"
+#include "hw/net/npcm_gmac.h"
 #include "hw/nvram/npcm7xx_otp.h"
 #include "hw/timer/npcm7xx_timer.h"
 #include "hw/ssi/npcm7xx_fiu.h"
@@ -105,6 +106,7 @@ struct NPCM7xxState {
 OHCISysBusState ohci;
 NPCM7xxFIUState fiu[2];
 NPCM7xxEMCState emc[2];
+NPCMGMACState   gmac[2];
 NPCM7xxPCIMBoxState pci_mbox;
 NPCM7xxSDHCIState   mmc;
 NPCMPSPIState   pspi[2];
-- 
2.42.0.655.g421f12c284-goog




[PATCH v3 04/11] hw/net: Add NPCMXXX GMAC device

2023-10-17 Thread Nabih Estefan
From: Hao Wu 

This patch implements the basic registers of GMAC device. Actual network
communications are not supported yet.

Signed-off-by: Hao Wu 

include/hw: Fix type problem in NPCMGMACState

- Fix type problem in NPCMGMACState
- Fix Register Initalization which was breaking boot-up in driver
- Added trace for NPCM_GMAC reset
- Added nd_table to npcm8xx.c for GMAC bootup

Signed-off-by: Nabih Estefan Diaz 

hw/net: Add BCM54612E PHY regs for GMAC

This patch adds default values for PHYs to make the driver happy.
The device is derived from an actual Izumi machine.

Signed-off-by: Hao Wu 

hw/net: change GMAC PHY regs to indicate link is up

This change makes NPCM GMAC module to use BCM54612E unconditionally
and make some fake PHY registers such that the kernel driver thinks
the link partner is up.

Tested:
The following message shows up with the change:
Broadcom BCM54612E stmmac-0:00: attached PHY driver [Broadcom BCM54612E] 
(mii_bus:phy_addr=stmmac-0:00, irq=POLL)
stmmaceth f0802000.eth eth0: Link is Up - 1Gbps/Full - flow control rx/tx

Signed-off-by: Hao Wu 
---
 hw/net/meson.build |   2 +-
 hw/net/npcm_gmac.c | 395 +
 hw/net/trace-events|  11 ++
 include/hw/net/npcm_gmac.h | 170 
 4 files changed, 577 insertions(+), 1 deletion(-)
 create mode 100644 hw/net/npcm_gmac.c
 create mode 100644 include/hw/net/npcm_gmac.h

diff --git a/hw/net/meson.build b/hw/net/meson.build
index 2632634df3..8389a134d5 100644
--- a/hw/net/meson.build
+++ b/hw/net/meson.build
@@ -38,7 +38,7 @@ system_ss.add(when: 'CONFIG_I82596_COMMON', if_true: 
files('i82596.c'))
 system_ss.add(when: 'CONFIG_SUNHME', if_true: files('sunhme.c'))
 system_ss.add(when: 'CONFIG_FTGMAC100', if_true: files('ftgmac100.c'))
 system_ss.add(when: 'CONFIG_SUNGEM', if_true: files('sungem.c'))
-system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c'))
+system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c', 
'npcm_gmac.c'))
 
 system_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_eth.c'))
 system_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c'))
diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c
new file mode 100644
index 00..5ce632858d
--- /dev/null
+++ b/hw/net/npcm_gmac.c
@@ -0,0 +1,395 @@
+/*
+ * Nuvoton NPCM7xx/8xx GMAC Module
+ *
+ * Copyright 2022 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * Unsupported/unimplemented features:
+ * - MII is not implemented, MII_ADDR.BUSY and MII_DATA always return zero
+ * - Precision timestamp (PTP) is not implemented.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/registerfields.h"
+#include "hw/net/mii.h"
+#include "hw/net/npcm_gmac.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+#include "qemu/units.h"
+#include "sysemu/dma.h"
+#include "trace.h"
+
+REG32(NPCM_DMA_BUS_MODE, 0x1000)
+REG32(NPCM_DMA_XMT_POLL_DEMAND, 0x1004)
+REG32(NPCM_DMA_RCV_POLL_DEMAND, 0x1008)
+REG32(NPCM_DMA_RCV_BASE_ADDR, 0x100c)
+REG32(NPCM_DMA_TX_BASE_ADDR, 0x1010)
+REG32(NPCM_DMA_STATUS, 0x1014)
+REG32(NPCM_DMA_CONTROL, 0x1018)
+REG32(NPCM_DMA_INTR_ENA, 0x101c)
+REG32(NPCM_DMA_MISSED_FRAME_CTR, 0x1020)
+REG32(NPCM_DMA_HOST_TX_DESC, 0x1048)
+REG32(NPCM_DMA_HOST_RX_DESC, 0x104c)
+REG32(NPCM_DMA_CUR_TX_BUF_ADDR, 0x1050)
+REG32(NPCM_DMA_CUR_RX_BUF_ADDR, 0x1054)
+REG32(NPCM_DMA_HW_FEATURE, 0x1058)
+
+REG32(NPCM_GMAC_MAC_CONFIG, 0x0)
+REG32(NPCM_GMAC_FRAME_FILTER, 0x4)
+REG32(NPCM_GMAC_HASH_HIGH, 0x8)
+REG32(NPCM_GMAC_HASH_LOW, 0xc)
+REG32(NPCM_GMAC_MII_ADDR, 0x10)
+REG32(NPCM_GMAC_MII_DATA, 0x14)
+REG32(NPCM_GMAC_FLOW_CTRL, 0x18)
+REG32(NPCM_GMAC_VLAN_FLAG, 0x1c)
+REG32(NPCM_GMAC_VERSION, 0x20)
+REG32(NPCM_GMAC_WAKEUP_FILTER, 0x28)
+REG32(NPCM_GMAC_PMT, 0x2c)
+REG32(NPCM_GMAC_LPI_CTRL, 0x30)
+REG32(NPCM_GMAC_TIMER_CTRL, 0x34)
+REG32(NPCM_GMAC_INT_STATUS, 0x38)
+REG32(NPCM_GMAC_INT_MASK, 0x3c)
+REG32(NPCM_GMAC_MAC0_ADDR_HI, 0x40)
+REG32(NPCM_GMAC_MAC0_ADDR_LO, 0x44)
+REG32(NPCM_GMAC_MAC1_ADDR_HI, 0x48)
+REG32(NPCM_GMAC_MAC1_ADDR_LO, 0x4c)
+REG32(NPCM_GMAC_MAC2_ADDR_HI, 0x50)
+REG32(NPCM_GMAC_MAC2_ADDR_LO, 0x54)
+REG32(NPCM_GMAC_MAC3_ADDR_HI, 0x58)
+REG32(NPCM_GMAC_MAC3_ADDR_LO, 0x5c)
+REG32(NPCM_GMAC_RGMII_STATUS, 0xd8)
+REG32(NPCM_GMAC_WATCHDOG, 0xdc)
+REG32(NPCM_GMAC_PTP_TCR, 0x700)
+REG32(NPCM_GMAC_PTP_SSIR, 0x704)
+REG32(NPCM_GMAC_PTP_STSR, 0x708)
+REG32(NPCM_GMAC_PTP_STNSR, 0x70c)
+REG32(NPCM_GMAC_PTP_STSUR, 0x710)
+REG32(NPCM_GMAC_PTP_STNSUR, 0x714)
+REG32(NPCM_GMAC_PTP_TAR, 0x718)
+REG32(NPCM_GMAC_PTP_TTSR, 

[PATCH v3 01/11] hw/misc: Add Nuvoton's PCI Mailbox Module

2023-10-17 Thread Nabih Estefan
From: Hao Wu 

The PCI Mailbox Module is a high-bandwidth communcation module
between a Nuvoton BMC and CPU. It features 16KB RAM that are both
accessible by the BMC and core CPU. and supports interrupt for
both sides.

This patch implements the BMC side of the PCI mailbox module.
Communication with the core CPU is emulated via a chardev and
will be in a follow-up patch.

Signed-off-by: Hao Wu 
---
 hw/arm/npcm7xx.c   |  16 +-
 hw/misc/meson.build|   1 +
 hw/misc/npcm7xx_pci_mbox.c | 324 +
 hw/misc/trace-events   |   5 +
 include/hw/arm/npcm7xx.h   |   1 +
 include/hw/misc/npcm7xx_pci_mbox.h |  81 
 6 files changed, 427 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/npcm7xx_pci_mbox.c
 create mode 100644 include/hw/misc/npcm7xx_pci_mbox.h

diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 15ff21d047..c69e936669 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -53,6 +53,9 @@
 /* ADC Module */
 #define NPCM7XX_ADC_BA  (0xf000c000)
 
+/* PCI Mailbox Module */
+#define NPCM7XX_PCI_MBOX_BA (0xf0848000)
+
 /* Internal AHB SRAM */
 #define NPCM7XX_RAM3_BA (0xc0008000)
 #define NPCM7XX_RAM3_SZ (4 * KiB)
@@ -83,6 +86,10 @@ enum NPCM7xxInterrupt {
 NPCM7XX_UART1_IRQ,
 NPCM7XX_UART2_IRQ,
 NPCM7XX_UART3_IRQ,
+NPCM7XX_PECI_IRQ= 6,
+NPCM7XX_PCI_MBOX_IRQ= 8,
+NPCM7XX_KCS_HIB_IRQ = 9,
+NPCM7XX_GMAC1_IRQ   = 14,
 NPCM7XX_EMC1RX_IRQ  = 15,
 NPCM7XX_EMC1TX_IRQ,
 NPCM7XX_MMC_IRQ = 26,
@@ -706,6 +713,14 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 }
 }
 
+/* PCI Mailbox. Cannot fail */
+sysbus_realize(SYS_BUS_DEVICE(>pci_mbox), _abort);
+sysbus_mmio_map(SYS_BUS_DEVICE(>pci_mbox), 0, NPCM7XX_PCI_MBOX_BA);
+sysbus_mmio_map(SYS_BUS_DEVICE(>pci_mbox), 1,
+NPCM7XX_PCI_MBOX_BA + NPCM7XX_PCI_MBOX_RAM_SIZE);
+sysbus_connect_irq(SYS_BUS_DEVICE(>pci_mbox), 0,
+   npcm7xx_irq(s, NPCM7XX_PCI_MBOX_IRQ));
+
 /* RAM2 (SRAM) */
 memory_region_init_ram(>sram, OBJECT(dev), "ram2",
NPCM7XX_RAM2_SZ, _abort);
@@ -765,7 +780,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.usbd[8]",  0xf0838000,   4 * KiB);
 create_unimplemented_device("npcm7xx.usbd[9]",  0xf0839000,   4 * KiB);
 create_unimplemented_device("npcm7xx.sd",   0xf084,   8 * KiB);
-create_unimplemented_device("npcm7xx.pcimbx",   0xf0848000, 512 * KiB);
 create_unimplemented_device("npcm7xx.aes",  0xf0858000,   4 * KiB);
 create_unimplemented_device("npcm7xx.des",  0xf0859000,   4 * KiB);
 create_unimplemented_device("npcm7xx.sha",  0xf085a000,   4 * KiB);
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index f60de33f9a..3ee3f2226f 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -73,6 +73,7 @@ system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files(
   'npcm7xx_clk.c',
   'npcm7xx_gcr.c',
   'npcm7xx_mft.c',
+  'npcm7xx_pci_mbox.c',
   'npcm7xx_pwm.c',
   'npcm7xx_rng.c',
 ))
diff --git a/hw/misc/npcm7xx_pci_mbox.c b/hw/misc/npcm7xx_pci_mbox.c
new file mode 100644
index 00..c770ad6fcf
--- /dev/null
+++ b/hw/misc/npcm7xx_pci_mbox.c
@@ -0,0 +1,324 @@
+/*
+ * Nuvoton NPCM7xx PCI Mailbox Module
+ *
+ * Copyright 2021 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "chardev/char-fe.h"
+#include "hw/irq.h"
+#include "hw/qdev-clock.h"
+#include "hw/qdev-properties-system.h"
+#include "hw/misc/npcm7xx_pci_mbox.h"
+#include "hw/registerfields.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "qemu/bitops.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "qemu/units.h"
+#include "trace.h"
+
+REG32(NPCM7XX_PCI_MBOX_BMBXSTAT, 0x00);
+REG32(NPCM7XX_PCI_MBOX_BMBXCTL, 0x04);
+REG32(NPCM7XX_PCI_MBOX_BMBXCMD, 0x08);
+
+enum NPCM7xxPCIMBoxOperation {
+NPCM7XX_PCI_MBOX_OP_READ = 1,
+NPCM7XX_PCI_MBOX_OP_WRITE,
+};
+
+#define NPCM7XX_PCI_MBOX_OFFSET_BYTES 8
+
+/* Response code */
+#define NPCM7XX_PCI_MBOX_OK 0
+#define NPCM7XX_PCI_MBOX_INVALID_OP 0xa0
+#define NPCM7XX_PCI_MBOX_INVALID_SIZE 0xa1
+#define NPCM7XX_PCI_MBOX_UNSPECIFIED_ERROR 0xff
+
+#define 

[PATCH v3 06/11] \tests/qtest: Creating qtest for GMAC Module

2023-10-17 Thread Nabih Estefan
From: Nabih Estefan Diaz 

 - Created qtest to check initialization of registers in GMAC Module.
 - Implemented test into Build File.

Signed-off-by: Nabih Estefan Diaz 
---
 tests/qtest/meson.build  |  11 +-
 tests/qtest/npcm_gmac-test.c | 209 +++
 2 files changed, 215 insertions(+), 5 deletions(-)
 create mode 100644 tests/qtest/npcm_gmac-test.c

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 05d26e9292..3ff9f5d364 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -191,6 +191,8 @@ qtests_npcm7xx = \
'npcm7xx_timer-test',
'npcm7xx_watchdog_timer-test'] + \
(slirp.found() ? ['npcm7xx_emc-test'] : [])
+qtests_npcm8xx = \
+  ['npcm_gmac-test']
 qtests_aspeed = \
   ['aspeed_hace-test',
'aspeed_smc-test',
@@ -205,9 +207,7 @@ qtests_arm = \
   (config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed : []) + \
   (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
   (config_all_devices.has_key('CONFIG_GENERIC_LOADER') ? ['hexloader-test'] : 
[]) + \
-  (config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : 
[]) + \
-  (config_all_devices.has_key('CONFIG_VEXPRESS') ? ['test-arm-mptimer'] : []) 
+ \
-  (config_all_devices.has_key('CONFIG_MICROBIT') ? ['microbit-test'] : []) + \
+  (config_all_devices.has_key('CONFIG_NPCM8XX') ? qtests_npcm8xx : []) + \
   ['arm-cpu-features',
'boot-serial-test']
 
@@ -219,8 +219,9 @@ qtests_aarch64 = \
   (config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ? ['xlnx-can-test', 
'fuzz-xlnx-dp-test'] : []) + \
   (config_all_devices.has_key('CONFIG_XLNX_VERSAL') ? ['xlnx-canfd-test'] : 
[]) + \
   (config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) +  \
-  (config_all.has_key('CONFIG_TCG') and
\
-   config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : 
[]) + \
+  (config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed : []) + \
+  (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
+  (config_all_devices.has_key('CONFIG_NPCM8XX') ? qtests_npcm8xx : []) + \
   ['arm-cpu-features',
'numa-test',
'boot-serial-test',
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
new file mode 100644
index 00..30d27e8dcc
--- /dev/null
+++ b/tests/qtest/npcm_gmac-test.c
@@ -0,0 +1,209 @@
+/*
+ * QTests for Nuvoton NPCM7xx/8xx GMAC Modules.
+ *
+ * Copyright 2022 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "libqos/libqos.h"
+
+/* Name of the GMAC Device */
+#define TYPE_NPCM_GMAC "npcm-gmac"
+
+typedef struct GMACModule {
+int irq;
+uint64_t base_addr;
+} GMACModule;
+
+typedef struct TestData {
+const GMACModule *module;
+} TestData;
+
+/* Values extracted from hw/arm/npcm8xx.c */
+static const GMACModule gmac_module_list[] = {
+{
+.irq= 14,
+.base_addr  = 0xf0802000
+},
+{
+.irq= 15,
+.base_addr  = 0xf0804000
+},
+{
+.irq= 16,
+.base_addr  = 0xf0806000
+},
+{
+.irq= 17,
+.base_addr  = 0xf0808000
+}
+};
+
+/* Returns the index of the GMAC module. */
+static int gmac_module_index(const GMACModule *mod)
+{
+ptrdiff_t diff = mod - gmac_module_list;
+
+g_assert_true(diff >= 0 && diff < ARRAY_SIZE(gmac_module_list));
+
+return diff;
+}
+
+/* 32-bit register indices. Taken from npcm_gmac.c */
+typedef enum NPCMRegister {
+/* DMA Registers */
+NPCM_DMA_BUS_MODE = 0x1000,
+NPCM_DMA_XMT_POLL_DEMAND = 0x1004,
+NPCM_DMA_RCV_POLL_DEMAND = 0x1008,
+NPCM_DMA_RCV_BASE_ADDR = 0x100c,
+NPCM_DMA_TX_BASE_ADDR = 0x1010,
+NPCM_DMA_STATUS = 0x1014,
+NPCM_DMA_CONTROL = 0x1018,
+NPCM_DMA_INTR_ENA = 0x101c,
+NPCM_DMA_MISSED_FRAME_CTR = 0x1020,
+NPCM_DMA_HOST_TX_DESC = 0x1048,
+NPCM_DMA_HOST_RX_DESC = 0x104c,
+NPCM_DMA_CUR_TX_BUF_ADDR = 0x1050,
+NPCM_DMA_CUR_RX_BUF_ADDR = 0x1054,
+NPCM_DMA_HW_FEATURE = 0x1058,
+
+/* GMAC Registers */
+NPCM_GMAC_MAC_CONFIG = 0x0,
+NPCM_GMAC_FRAME_FILTER = 0x4,
+NPCM_GMAC_HASH_HIGH = 0x8,
+NPCM_GMAC_HASH_LOW = 0xc,
+NPCM_GMAC_MII_ADDR = 0x10,
+NPCM_GMAC_MII_DATA = 0x14,
+NPCM_GMAC_FLOW_CTRL = 0x18,
+NPCM_GMAC_VLAN_FLAG = 0x1c,
+NPCM_GMAC_VERSION = 0x20,
+NPCM_GMAC_WAKEUP_FILTER = 0x28,
+NPCM_GMAC_PMT = 0x2c,
+

[PATCH v3 09/11] hw/net: GMAC Rx Implementation

2023-10-17 Thread Nabih Estefan
From: Nabih Estefan Diaz 

- Implementation of Receive function for packets
- Implementation for reading and writing from and to descriptors in
  memory for Rx

NOTE: At this point in development we believe this function is working
as intended, and the kernel supports these findings, but we need the
Transmit function to work before we upload

Signed-off-by: Nabih Estefan Diaz 

hw/net: npcm_gmac Flush queued packets when starting RX

When RX starts, we need to flush the queued packets so that they
can be received by the GMAC device. Without this it won't work
with TAP NIC device.

Signed-off-by: Hao Wu 

hw/net: Handle RX desc full in NPCM GMAC

When RX descriptor list is full, it returns a DMA_STATUS for software to handle 
it. But there's no way to indicate the software ha handled all RX descriptors 
and the whole pipeline stalls.

We do something similar to NPCM7XX EMC to handle this case.

1. Return packet size when RX descriptor is full, effectively dropping these 
packets in such a case.
2. When software clears RX descriptor full bit, continue receiving further 
packets by flushing QEMU packet queue.

Signed-off-by: Hao Wu 

hw/net: Receive and drop packets when descriptors are full in GMAC

Effectively this allows QEMU to receive and drop incoming packets when
RX descriptors are full. Similar to EMC, this lets GMAC to drop packets
faster, especially during bootup sequence.

Signed-off-by: Hao Wu 

hw/net: Update frame_ptr during gmac_receive

There was a bug that frame_ptr wasn't updated after receiving
the first batch of data, causing the received data to be wrong
when the frame is too large.

Signed-off-by: Hao Wu 

hw/net: Fix GMAC not detecting owned by software properly in RX

RX should stop receiving when a descriptor is owned by software
but currently implementation made it reversed (owned by DMA) instead.

Signed-off-by: Hao Wu 

hw/net: Fix GMAC receive problem

Fix the following 2 problems in GMAC receive function:

1. When kernel driver disables GMAC RX interrupt and all descriptors
are full, it will not send further interrupt to the kernel
driver as the driver doesn't listen to NPCM_DMA_STATUS_RU.
Since descriptors full indicates that there are packets received
we should also set NPCM_DMA_STATUS_RI for firing the interrupt.
2. Kernel driver does not clear rdes0 from used descriptor so we need
to clear it such that old flags are removed before setting new
flags.

Signed-off-by: Hao Wu 
---
 hw/net/npcm_gmac.c | 356 ++---
 include/hw/net/npcm_gmac.h |  28 +--
 2 files changed, 342 insertions(+), 42 deletions(-)

diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c
index 6f8109e0ee..a7c8b67223 100644
--- a/hw/net/npcm_gmac.c
+++ b/hw/net/npcm_gmac.c
@@ -23,7 +23,11 @@
 #include "hw/registerfields.h"
 #include "hw/net/mii.h"
 #include "hw/net/npcm_gmac.h"
+#include "linux/if_ether.h"
 #include "migration/vmstate.h"
+#include "net/checksum.h"
+#include "net/net.h"
+#include "qemu/cutils.h"
 #include "qemu/log.h"
 #include "qemu/units.h"
 #include "sysemu/dma.h"
@@ -91,7 +95,6 @@ REG32(NPCM_GMAC_PTP_TTSR, 0x71c)
 #define NPCM_DMA_BUS_MODE_SWR   BIT(0)
 
 static const uint32_t npcm_gmac_cold_reset_values[NPCM_GMAC_NR_REGS] = {
-/* Reduce version to 3.2 so that the kernel can enable interrupt. */
 [R_NPCM_GMAC_VERSION] = 0x1032,
 [R_NPCM_GMAC_TIMER_CTRL]  = 0x03e8,
 [R_NPCM_GMAC_MAC0_ADDR_HI]= 0x8000,
@@ -146,6 +149,17 @@ static void gmac_phy_set_link(NPCMGMACState *s, bool 
active)
 
 static bool gmac_can_receive(NetClientState *nc)
 {
+NPCMGMACState *gmac = NPCM_GMAC(qemu_get_nic_opaque(nc));
+
+/* If GMAC receive is disabled. */
+if (!(gmac->regs[R_NPCM_GMAC_MAC_CONFIG] & NPCM_GMAC_MAC_CONFIG_RX_EN)) {
+return false;
+}
+
+/* If GMAC DMA RX is stopped. */
+if (!(gmac->regs[R_NPCM_DMA_CONTROL] & NPCM_DMA_CONTROL_START_STOP_RX)) {
+return false;
+}
 return true;
 }
 
@@ -191,11 +205,288 @@ static void gmac_update_irq(NPCMGMACState *gmac)
 qemu_set_irq(gmac->irq, level);
 }
 
-static ssize_t gmac_receive(NetClientState *nc, const uint8_t *buf, size_t len)
+static int gmac_read_rx_desc(dma_addr_t addr, struct NPCMGMACRxDesc *desc)
 {
-/* Placeholder */
+if (dma_memory_read(_space_memory, addr, desc,
+sizeof(*desc), MEMTXATTRS_UNSPECIFIED)) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read descriptor @ 0x%"
+  HWADDR_PRIx "\n", __func__, addr);
+return -1;
+}
+desc->rdes0 = le32_to_cpu(desc->rdes0);
+desc->rdes1 = le32_to_cpu(desc->rdes1);
+desc->rdes2 = le32_to_cpu(desc->rdes2);
+desc->rdes3 = le32_to_cpu(desc->rdes3);
+return 0;
+}
+
+static int gmac_write_rx_desc(dma_addr_t addr, struct NPCMGMACRxDesc *desc)
+{
+struct NPCMGMACRxDesc le_desc;
+le_desc.rdes0 = cpu_to_le32(desc->rdes0);
+le_desc.rdes1 = 

[PATCH v3 10/11] hw/net: GMAC Tx Implementation

2023-10-17 Thread Nabih Estefan
From: Nabih Estefan Diaz 

- Implementation of Transmit function for packets
- Implementation for reading and writing from and to descriptors in
  memory for Tx

NOTE: This function implements the steps detailed in the datasheet for
transmitting messages from the GMAC.

Signed-off-by: Nabih Estefan Diaz 
---
 hw/net/npcm_gmac.c | 152 +
 1 file changed, 152 insertions(+)

diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c
index a7c8b67223..688ac4be44 100644
--- a/hw/net/npcm_gmac.c
+++ b/hw/net/npcm_gmac.c
@@ -266,6 +266,7 @@ static int gmac_write_tx_desc(dma_addr_t addr, struct 
NPCMGMACTxDesc *desc)
 }
 return 0;
 }
+
 static int gmac_rx_transfer_frame_to_buffer(uint32_t rx_buf_len,
 uint32_t *left_frame,
 uint32_t rx_buf_addr,
@@ -487,6 +488,157 @@ static ssize_t gmac_receive(NetClientState *nc, const 
uint8_t *buf, size_t len)
 gmac->regs[R_NPCM_DMA_HOST_RX_DESC] = desc_addr;
 return len;
 }
+
+static int gmac_tx_get_csum(uint32_t tdes1)
+{
+uint32_t mask = TX_DESC_TDES1_CHKSM_INS_CTRL_MASK(tdes1);
+int csum = 0;
+
+if (likely(mask > 0)) {
+csum |= CSUM_IP;
+}
+if (likely(mask > 1)) {
+csum |= CSUM_TCP | CSUM_UDP;
+}
+
+return csum;
+}
+
+static void gmac_try_send_next_packet(NPCMGMACState *gmac)
+{
+/*
+ * Comments about steps refer to steps for
+ * transmitting in page 384 of datasheet
+ */
+uint16_t tx_buffer_size = 2048;
+g_autofree uint8_t *tx_send_buffer = g_malloc(tx_buffer_size);
+uint32_t desc_addr;
+struct NPCMGMACTxDesc tx_desc;
+uint32_t tx_buf_addr, tx_buf_len;
+uint16_t length = 0;
+uint8_t *buf = tx_send_buffer;
+uint32_t prev_buf_size = 0;
+int csum = 0;
+
+/* steps 1&2 */
+if (!gmac->regs[R_NPCM_DMA_HOST_TX_DESC]) {
+gmac->regs[R_NPCM_DMA_HOST_TX_DESC] =
+NPCM_DMA_HOST_TX_DESC_MASK(gmac->regs[R_NPCM_DMA_TX_BASE_ADDR]);
+}
+desc_addr = gmac->regs[R_NPCM_DMA_HOST_TX_DESC];
+
+while (true) {
+gmac_dma_set_state(gmac, NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT,
+NPCM_DMA_STATUS_TX_RUNNING_FETCHING_STATE);
+trace_npcm_gmac_packet_transmit(DEVICE(gmac)->canonical_path, length);
+if (gmac_read_tx_desc(desc_addr, _desc)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "TX Descriptor @ 0x%x can't be read\n",
+  desc_addr);
+return;
+}
+/* step 3 */
+
+trace_npcm_gmac_packet_desc_read(DEVICE(gmac)->canonical_path,
+desc_addr);
+trace_npcm_gmac_debug_desc_data(DEVICE(gmac)->canonical_path, _desc,
+tx_desc.tdes0, tx_desc.tdes1, tx_desc.tdes2, tx_desc.tdes3);
+
+/* 1 = DMA Owned, 0 = Software Owned */
+if (!(tx_desc.tdes0 & TX_DESC_TDES0_OWN)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "TX Descriptor @ 0x%x is owned by software\n",
+  desc_addr);
+gmac->regs[R_NPCM_DMA_STATUS] |= NPCM_DMA_STATUS_TU;
+gmac_dma_set_state(gmac, NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT,
+NPCM_DMA_STATUS_TX_SUSPENDED_STATE);
+gmac_update_irq(gmac);
+return;
+}
+
+gmac_dma_set_state(gmac, NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT,
+NPCM_DMA_STATUS_TX_RUNNING_READ_STATE);
+/* Give the descriptor back regardless of what happens. */
+tx_desc.tdes0 &= ~TX_DESC_TDES0_OWN;
+
+if (tx_desc.tdes1 & TX_DESC_TDES1_FIRST_SEG_MASK) {
+csum = gmac_tx_get_csum(tx_desc.tdes1);
+}
+
+/* step 4 */
+tx_buf_addr = tx_desc.tdes2;
+gmac->regs[R_NPCM_DMA_CUR_TX_BUF_ADDR] = tx_buf_addr;
+tx_buf_len = TX_DESC_TDES1_BFFR1_SZ_MASK(tx_desc.tdes1);
+buf = _send_buffer[prev_buf_size];
+
+if ((prev_buf_size + tx_buf_len) > sizeof(buf)) {
+tx_buffer_size = prev_buf_size + tx_buf_len;
+tx_send_buffer = g_realloc(tx_send_buffer, tx_buffer_size);
+buf = _send_buffer[prev_buf_size];
+}
+
+/* step 5 */
+if (dma_memory_read(_space_memory, tx_buf_addr, buf,
+tx_buf_len, MEMTXATTRS_UNSPECIFIED)) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read packet @ 
0x%x\n",
+__func__, tx_buf_addr);
+return;
+}
+length += tx_buf_len;
+prev_buf_size += tx_buf_len;
+
+/* If not chained we'll have a second buffer. */
+if (!(tx_desc.tdes1 & TX_DESC_TDES1_SEC_ADDR_CHND_MASK)) {
+tx_buf_addr = tx_desc.tdes3;
+gmac->regs[R_NPCM_DMA_CUR_TX_BUF_ADDR] = tx_buf_addr;
+tx_buf_len = TX_DESC_TDES1_BFFR2_SZ_MASK(tx_desc.tdes1);
+buf = _send_buffer[prev_buf_size];
+
+if 

[PATCH v3 03/11] hw/misc: Add qtest for NPCM7xx PCI Mailbox

2023-10-17 Thread Nabih Estefan
From: Hao Wu 

This patches adds a qtest for NPCM7XX PCI Mailbox module.
It sends read and write requests to the module, and verifies that
the module contains the correct data after the requests.

Signed-off-by: Hao Wu 
---
 tests/qtest/meson.build |   1 +
 tests/qtest/npcm7xx_pci_mbox-test.c | 238 
 2 files changed, 239 insertions(+)
 create mode 100644 tests/qtest/npcm7xx_pci_mbox-test.c

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 66795cfcd2..05d26e9292 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -183,6 +183,7 @@ qtests_sparc64 = \
 qtests_npcm7xx = \
   ['npcm7xx_adc-test',
'npcm7xx_gpio-test',
+   'npcm7xx_pci_mbox-test',
'npcm7xx_pwm-test',
'npcm7xx_rng-test',
'npcm7xx_sdhci-test',
diff --git a/tests/qtest/npcm7xx_pci_mbox-test.c 
b/tests/qtest/npcm7xx_pci_mbox-test.c
new file mode 100644
index 00..24eec18e3c
--- /dev/null
+++ b/tests/qtest/npcm7xx_pci_mbox-test.c
@@ -0,0 +1,238 @@
+/*
+ * QTests for Nuvoton NPCM7xx PCI Mailbox Modules.
+ *
+ * Copyright 2021 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bitops.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qnum.h"
+#include "libqtest-single.h"
+
+#define PCI_MBOX_BA 0xf0848000
+#define PCI_MBOX_IRQ8
+
+/* register offset */
+#define PCI_MBOX_STAT   0x00
+#define PCI_MBOX_CTL0x04
+#define PCI_MBOX_CMD0x08
+
+#define CODE_OK 0x00
+#define CODE_INVALID_OP 0xa0
+#define CODE_INVALID_SIZE   0xa1
+#define CODE_ERROR  0xff
+
+#define OP_READ 0x01
+#define OP_WRITE0x02
+#define OP_INVALID  0x41
+
+
+static int sock;
+static int fd;
+
+/*
+ * Create a local TCP socket with any port, then save off the port we got.
+ */
+static in_port_t open_socket(void)
+{
+struct sockaddr_in myaddr;
+socklen_t addrlen;
+
+myaddr.sin_family = AF_INET;
+myaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+myaddr.sin_port = 0;
+sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+g_assert(sock != -1);
+g_assert(bind(sock, (struct sockaddr *) , sizeof(myaddr)) != -1);
+addrlen = sizeof(myaddr);
+g_assert(getsockname(sock, (struct sockaddr *)  , ) != -1);
+g_assert(listen(sock, 1) != -1);
+return ntohs(myaddr.sin_port);
+}
+
+static void setup_fd(void)
+{
+fd_set readfds;
+
+FD_ZERO();
+FD_SET(sock, );
+g_assert(select(sock + 1, , NULL, NULL, NULL) == 1);
+
+fd = accept(sock, NULL, 0);
+g_assert(fd >= 0);
+}
+
+static uint8_t read_response(uint8_t *buf, size_t len)
+{
+uint8_t code;
+ssize_t ret = read(fd, , 1);
+
+if (ret == -1) {
+return CODE_ERROR;
+}
+if (code != CODE_OK) {
+return code;
+}
+g_test_message("response code: %x", code);
+if (len > 0) {
+ret = read(fd, buf, len);
+if (ret < len) {
+return CODE_ERROR;
+}
+}
+return CODE_OK;
+}
+
+static void receive_data(uint64_t offset, uint8_t *buf, size_t len)
+{
+uint8_t op = OP_READ;
+uint8_t code;
+ssize_t rv;
+
+while (len > 0) {
+uint8_t size;
+
+if (len >= 8) {
+size = 8;
+} else if (len >= 4) {
+size = 4;
+} else if (len >= 2) {
+size = 2;
+} else {
+size = 1;
+}
+
+g_test_message("receiving %u bytes", size);
+/* Write op */
+rv = write(fd, , 1);
+g_assert_cmpint(rv, ==, 1);
+/* Write offset */
+rv = write(fd, (uint8_t *), sizeof(uint64_t));
+g_assert_cmpint(rv, ==, sizeof(uint64_t));
+/* Write size */
+g_assert_cmpint(write(fd, , 1), ==, 1);
+
+/* Read data and Expect response */
+code = read_response(buf, size);
+g_assert_cmphex(code, ==, CODE_OK);
+
+buf += size;
+offset += size;
+len -= size;
+}
+}
+
+static void send_data(uint64_t offset, const uint8_t *buf, size_t len)
+{
+uint8_t op = OP_WRITE;
+uint8_t code;
+ssize_t rv;
+
+while (len > 0) {
+uint8_t size;
+
+if (len >= 8) {
+size = 8;
+} else if (len >= 4) {
+size = 4;
+} else if (len >= 2) {
+size = 2;
+} else {
+size = 1;
+}
+
+g_test_message("sending %u bytes", size);
+/* Write op */
+rv = write(fd, , 1);
+   

[PATCH v3 11/11] tests/qtest: Adding PCS Module test to GMAC Qtest

2023-10-17 Thread Nabih Estefan
From: Nabih Estefan Diaz 

 - Add PCS Register check to npcm_gmac-test

Signed-off-by: Nabih Estefan Diaz 
---
 tests/qtest/npcm_gmac-test.c | 134 ++-
 1 file changed, 133 insertions(+), 1 deletion(-)

diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
index 84511fd915..1f0ad664f4 100644
--- a/tests/qtest/npcm_gmac-test.c
+++ b/tests/qtest/npcm_gmac-test.c
@@ -20,6 +20,10 @@
 /* Name of the GMAC Device */
 #define TYPE_NPCM_GMAC "npcm-gmac"
 
+/* Address of the PCS Module */
+#define PCS_BASE_ADDRESS 0xf078
+#define NPCM_PCS_IND_AC_BA 0x1fe
+
 typedef struct GMACModule {
 int irq;
 uint64_t base_addr;
@@ -111,6 +115,62 @@ typedef enum NPCMRegister {
 NPCM_GMAC_PTP_STNSUR = 0x714,
 NPCM_GMAC_PTP_TAR = 0x718,
 NPCM_GMAC_PTP_TTSR = 0x71c,
+
+/* PCS Registers */
+NPCM_PCS_SR_CTL_ID1 = 0x3c0008,
+NPCM_PCS_SR_CTL_ID2 = 0x3c000a,
+NPCM_PCS_SR_CTL_STS = 0x3c0010,
+
+NPCM_PCS_SR_MII_CTRL = 0x3e,
+NPCM_PCS_SR_MII_STS = 0x3e0002,
+NPCM_PCS_SR_MII_DEV_ID1 = 0x3e0004,
+NPCM_PCS_SR_MII_DEV_ID2 = 0x3e0006,
+NPCM_PCS_SR_MII_AN_ADV = 0x3e0008,
+NPCM_PCS_SR_MII_LP_BABL = 0x3e000a,
+NPCM_PCS_SR_MII_AN_EXPN = 0x3e000c,
+NPCM_PCS_SR_MII_EXT_STS = 0x3e001e,
+
+NPCM_PCS_SR_TIM_SYNC_ABL = 0x3e0e10,
+NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR = 0x3e0e12,
+NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR = 0x3e0e14,
+NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR = 0x3e0e16,
+NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR = 0x3e0e18,
+NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR = 0x3e0e1a,
+NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR = 0x3e0e1c,
+NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR = 0x3e0e1e,
+NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR = 0x3e0e20,
+
+NPCM_PCS_VR_MII_MMD_DIG_CTRL1 = 0x3f,
+NPCM_PCS_VR_MII_AN_CTRL = 0x3f0002,
+NPCM_PCS_VR_MII_AN_INTR_STS = 0x3f0004,
+NPCM_PCS_VR_MII_TC = 0x3f0006,
+NPCM_PCS_VR_MII_DBG_CTRL = 0x3f000a,
+NPCM_PCS_VR_MII_EEE_MCTRL0 = 0x3f000c,
+NPCM_PCS_VR_MII_EEE_TXTIMER = 0x3f0010,
+NPCM_PCS_VR_MII_EEE_RXTIMER = 0x3f0012,
+NPCM_PCS_VR_MII_LINK_TIMER_CTRL = 0x3f0014,
+NPCM_PCS_VR_MII_EEE_MCTRL1 = 0x3f0016,
+NPCM_PCS_VR_MII_DIG_STS = 0x3f0020,
+NPCM_PCS_VR_MII_ICG_ERRCNT1 = 0x3f0022,
+NPCM_PCS_VR_MII_MISC_STS = 0x3f0030,
+NPCM_PCS_VR_MII_RX_LSTS = 0x3f0040,
+NPCM_PCS_VR_MII_MP_TX_BSTCTRL0 = 0x3f0070,
+NPCM_PCS_VR_MII_MP_TX_LVLCTRL0 = 0x3f0074,
+NPCM_PCS_VR_MII_MP_TX_GENCTRL0 = 0x3f007a,
+NPCM_PCS_VR_MII_MP_TX_GENCTRL1 = 0x3f007c,
+NPCM_PCS_VR_MII_MP_TX_STS = 0x3f0090,
+NPCM_PCS_VR_MII_MP_RX_GENCTRL0 = 0x3f00b0,
+NPCM_PCS_VR_MII_MP_RX_GENCTRL1 = 0x3f00b2,
+NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0 = 0x3f00ba,
+NPCM_PCS_VR_MII_MP_MPLL_CTRL0 = 0x3f00f0,
+NPCM_PCS_VR_MII_MP_MPLL_CTRL1 = 0x3f00f2,
+NPCM_PCS_VR_MII_MP_MPLL_STS = 0x3f0110,
+NPCM_PCS_VR_MII_MP_MISC_CTRL2 = 0x3f0126,
+NPCM_PCS_VR_MII_MP_LVL_CTRL = 0x3f0130,
+NPCM_PCS_VR_MII_MP_MISC_CTRL0 = 0x3f0132,
+NPCM_PCS_VR_MII_MP_MISC_CTRL1 = 0x3f0134,
+NPCM_PCS_VR_MII_DIG_CTRL2 = 0x3f01c2,
+NPCM_PCS_VR_MII_DIG_ERRCNT_SEL = 0x3f01c4,
 } NPCMRegister;
 
 static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
@@ -119,6 +179,15 @@ static uint32_t gmac_read(QTestState *qts, const 
GMACModule *mod,
 return qtest_readl(qts, mod->base_addr + regno);
 }
 
+static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
+  NPCMRegister regno)
+{
+uint32_t write_value = (regno & 0x3ffe00) >> 9;
+qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
+uint32_t read_offset = regno & 0x1ff;
+return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
+}
+
 /* Check that GMAC registers are reset to default value */
 static void test_init(gconstpointer test_data)
 {
@@ -129,7 +198,12 @@ static void test_init(gconstpointer test_data)
 #define CHECK_REG32(regno, value) \
 do { \
 g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
-} while (0)
+} while (0) ;
+
+#define CHECK_REG_PCS(regno, value) \
+do { \
+g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
+} while (0) ;
 
 CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
 CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
@@ -180,6 +254,64 @@ static void test_init(gconstpointer test_data)
 CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
 CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
 
+/* TODO Add registers PCS */
+if (mod->base_addr == 0xf0802000) {
+CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID1, 0x699e)
+CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID2, 0)
+CHECK_REG_PCS(NPCM_PCS_SR_CTL_STS, 0x8000)
+
+CHECK_REG_PCS(NPCM_PCS_SR_MII_CTRL, 0x1140)
+CHECK_REG_PCS(NPCM_PCS_SR_MII_STS, 0x0109)
+CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID1, 0x699e)
+CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID2, 0x0ced0)
+CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_ADV, 0x0020)
+

[PATCH v3 07/11] include/hw/net: Implemented Classes and Masks for GMAC Descriptors

2023-10-17 Thread Nabih Estefan
From: Nabih Estefan Diaz 

 - Implemeted classes for GMAC Receive and Transmit Descriptors
 - Implemented Masks for said descriptors

Signed-off-by: Nabih Estefan Diaz 
---
 hw/net/npcm_gmac.c   | 183 +++
 hw/net/trace-events  |   9 ++
 include/hw/net/npcm_gmac.h   |   2 -
 tests/qtest/npcm_gmac-test.c |   2 +-
 4 files changed, 150 insertions(+), 46 deletions(-)

diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c
index 5ce632858d..6f8109e0ee 100644
--- a/hw/net/npcm_gmac.c
+++ b/hw/net/npcm_gmac.c
@@ -32,7 +32,7 @@
 REG32(NPCM_DMA_BUS_MODE, 0x1000)
 REG32(NPCM_DMA_XMT_POLL_DEMAND, 0x1004)
 REG32(NPCM_DMA_RCV_POLL_DEMAND, 0x1008)
-REG32(NPCM_DMA_RCV_BASE_ADDR, 0x100c)
+REG32(NPCM_DMA_RX_BASE_ADDR, 0x100c)
 REG32(NPCM_DMA_TX_BASE_ADDR, 0x1010)
 REG32(NPCM_DMA_STATUS, 0x1014)
 REG32(NPCM_DMA_CONTROL, 0x1018)
@@ -91,7 +91,8 @@ REG32(NPCM_GMAC_PTP_TTSR, 0x71c)
 #define NPCM_DMA_BUS_MODE_SWR   BIT(0)
 
 static const uint32_t npcm_gmac_cold_reset_values[NPCM_GMAC_NR_REGS] = {
-[R_NPCM_GMAC_VERSION] = 0x1037,
+/* Reduce version to 3.2 so that the kernel can enable interrupt. */
+[R_NPCM_GMAC_VERSION] = 0x1032,
 [R_NPCM_GMAC_TIMER_CTRL]  = 0x03e8,
 [R_NPCM_GMAC_MAC0_ADDR_HI]= 0x8000,
 [R_NPCM_GMAC_MAC0_ADDR_LO]= 0x,
@@ -125,12 +126,12 @@ static const uint16_t phy_reg_init[] = {
 [MII_EXTSTAT]   = 0x3000, /* 1000BASTE_T full-duplex capable */
 };
 
-static void npcm_gmac_soft_reset(NPCMGMACState *s)
+static void npcm_gmac_soft_reset(NPCMGMACState *gmac)
 {
-memcpy(s->regs, npcm_gmac_cold_reset_values,
+memcpy(gmac->regs, npcm_gmac_cold_reset_values,
NPCM_GMAC_NR_REGS * sizeof(uint32_t));
 /* Clear reset bits */
-s->regs[R_NPCM_DMA_BUS_MODE] &= ~NPCM_DMA_BUS_MODE_SWR;
+gmac->regs[R_NPCM_DMA_BUS_MODE] &= ~NPCM_DMA_BUS_MODE_SWR;
 }
 
 static void gmac_phy_set_link(NPCMGMACState *s, bool active)
@@ -148,11 +149,53 @@ static bool gmac_can_receive(NetClientState *nc)
 return true;
 }
 
-static ssize_t gmac_receive(NetClientState *nc, const uint8_t *buf, size_t 
len1)
+/*
+ * Function that updates the GMAC IRQ
+ * It find the logical OR of the enabled bits for NIS (if enabled)
+ * It find the logical OR of the enabled bits for AIS (if enabled)
+ */
+static void gmac_update_irq(NPCMGMACState *gmac)
 {
-return 0;
+/*
+ * Check if the normal interrupts summery is enabled
+ * if so, add the bits for the summary that are enabled
+ */
+if (gmac->regs[R_NPCM_DMA_INTR_ENA] & gmac->regs[R_NPCM_DMA_STATUS] &
+(NPCM_DMA_INTR_ENAB_NIE_BITS))
+{
+gmac->regs[R_NPCM_DMA_STATUS] |=  NPCM_DMA_STATUS_NIS;
+}
+/*
+ * Check if the abnormal interrupts summery is enabled
+ * if so, add the bits for the summary that are enabled
+ */
+if (gmac->regs[R_NPCM_DMA_INTR_ENA] & gmac->regs[R_NPCM_DMA_STATUS] &
+(NPCM_DMA_INTR_ENAB_AIE_BITS))
+{
+gmac->regs[R_NPCM_DMA_STATUS] |=  NPCM_DMA_STATUS_AIS;
+}
+
+/* Get the logical OR of both normal and abnormal interrupts */
+int level = !!((gmac->regs[R_NPCM_DMA_STATUS] &
+gmac->regs[R_NPCM_DMA_INTR_ENA] &
+NPCM_DMA_STATUS_NIS) |
+   (gmac->regs[R_NPCM_DMA_STATUS] &
+   gmac->regs[R_NPCM_DMA_INTR_ENA] &
+   NPCM_DMA_STATUS_AIS));
+
+/* Set the IRQ */
+trace_npcm_gmac_update_irq(DEVICE(gmac)->canonical_path,
+   gmac->regs[R_NPCM_DMA_STATUS],
+   gmac->regs[R_NPCM_DMA_INTR_ENA],
+   level);
+qemu_set_irq(gmac->irq, level);
 }
 
+static ssize_t gmac_receive(NetClientState *nc, const uint8_t *buf, size_t len)
+{
+/* Placeholder */
+return 0;
+}
 static void gmac_cleanup(NetClientState *nc)
 {
 /* Nothing to do yet. */
@@ -166,7 +209,7 @@ static void gmac_set_link(NetClientState *nc)
 gmac_phy_set_link(s, !nc->link_down);
 }
 
-static void npcm_gmac_mdio_access(NPCMGMACState *s, uint16_t v)
+static void npcm_gmac_mdio_access(NPCMGMACState *gmac, uint16_t v)
 {
 bool busy = v & NPCM_GMAC_MII_ADDR_BUSY;
 uint8_t is_write;
@@ -183,33 +226,38 @@ static void npcm_gmac_mdio_access(NPCMGMACState *s, 
uint16_t v)
 
 
 if (v & NPCM_GMAC_MII_ADDR_WRITE) {
-data = s->regs[R_NPCM_GMAC_MII_DATA];
+data = gmac->regs[R_NPCM_GMAC_MII_DATA];
 /* Clear reset bit for BMCR register */
 switch (gr) {
 case MII_BMCR:
 data &= ~MII_BMCR_RESET;
-/* Complete auto-negotiation immediately and set as complete */
-if (data & MII_BMCR_AUTOEN) {
+/* Autonegotiation is a W1C bit*/
+if (data & MII_BMCR_ANRESTART) {
 /* Tells autonegotiation to not restart again */
 data &= 

[PATCH v3 00/11] Implementation of NPI Mailbox and GMAC Networking Module

2023-10-17 Thread Nabih Estefan
From: Nabih Estefan Diaz 

[Changes since v2]
Fixed bugs related to the RC functionality of the GMAC. Added and
squashed patches related to that.
[Changes since v1]
Fixed some errors in formatting.
Fixed a merge error that I didn't see in v1.
Removed Nuvoton 8xx references since that is a separate patch set.

[Original Cover]
Creates NPI Mailbox Module with data verification for read and write (internal 
and external),
wiring to the Nuvoton SoC, and QTests.

Also creates the GMAC Networking Module. Implements read and write 
functionalities with cooresponding descriptors
and registers. Also includes QTests for the different functionalities.

Hao Wu (5):
  hw/misc: Add Nuvoton's PCI Mailbox Module
  hw/arm: Add PCI mailbox module to Nuvoton SoC
  hw/misc: Add qtest for NPCM7xx PCI Mailbox
  hw/net: Add NPCMXXX GMAC device
  hw/arm: Add GMAC devices to NPCM7XX SoC

Nabih Estefan Diaz (6):
  \tests/qtest: Creating qtest for GMAC Module
  include/hw/net: Implemented Classes and Masks for GMAC Descriptors
  hw/net: General GMAC Implementation
  hw/net: GMAC Rx Implementation
  hw/net: GMAC Tx Implementation
  tests/qtest: Adding PCS Module test to GMAC Qtest

 docs/system/arm/nuvoton.rst |   2 +
 hw/arm/npcm7xx.c|  53 +-
 hw/misc/meson.build |   1 +
 hw/misc/npcm7xx_pci_mbox.c  | 324 ++
 hw/misc/trace-events|   5 +
 hw/net/meson.build  |   2 +-
 hw/net/npcm_gmac.c  | 942 
 hw/net/trace-events |  20 +
 include/hw/arm/npcm7xx.h|   4 +
 include/hw/misc/npcm7xx_pci_mbox.h  |  81 +++
 include/hw/net/npcm_gmac.h  | 340 ++
 tests/qtest/meson.build |  12 +-
 tests/qtest/npcm7xx_pci_mbox-test.c | 238 +++
 tests/qtest/npcm_gmac-test.c| 341 ++
 14 files changed, 2356 insertions(+), 9 deletions(-)
 create mode 100644 hw/misc/npcm7xx_pci_mbox.c
 create mode 100644 hw/net/npcm_gmac.c
 create mode 100644 include/hw/misc/npcm7xx_pci_mbox.h
 create mode 100644 include/hw/net/npcm_gmac.h
 create mode 100644 tests/qtest/npcm7xx_pci_mbox-test.c
 create mode 100644 tests/qtest/npcm_gmac-test.c

-- 
2.42.0.655.g421f12c284-goog




Re: [PATCH] migration: Fix parse_ramblock() on overwritten retvals

2023-10-17 Thread Fabiano Rosas
Peter Xu  writes:

> It's possible that some errors can be overwritten with success retval later
> on, and then ignored.  Always capture all errors and report.
>
> Reported by Coverity 1522861, but actually I spot one more in the same
> function.
>
> Fixes: CID 1522861
> Signed-off-by: Peter Xu 

Reviewed-by: Fabiano Rosas 



[PATCH] ppc/pnv: Connect PNV I2C controller to powernv10

2023-10-17 Thread Glenn Miles
Wires up four I2C controller instances to the powernv10 chip
XSCOM address space.

Each controller instance is wired up to two I2C buses of
its own.  No other I2C devices are connected to the buses
at this time.

Signed-off-by: Glenn Miles 
---
Based-on: <20231016222013.3739530-1-mil...@linux.vnet.ibm.com>
([PATCH v3 0/2] Add PowerNV I2C Controller Model)

 hw/ppc/pnv.c   | 29 +
 include/hw/ppc/pnv_chip.h  |  4 
 include/hw/ppc/pnv_xscom.h |  3 +++
 3 files changed, 36 insertions(+)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index e0b3478325..2655b6e506 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1695,6 +1695,10 @@ static void pnv_chip_power10_instance_init(Object *obj)
 object_initialize_child(obj, "pec[*]", >pecs[i],
 TYPE_PNV_PHB5_PEC);
 }
+
+for (i = 0; i < pcc->i2c_num_engines; i++) {
+object_initialize_child(obj, "i2c[*]", >i2c[i], TYPE_PNV_I2C);
+}
 }
 
 static void pnv_chip_power10_quad_realize(Pnv10Chip *chip10, Error **errp)
@@ -1753,6 +1757,7 @@ static void pnv_chip_power10_realize(DeviceState *dev, 
Error **errp)
 PnvChip *chip = PNV_CHIP(dev);
 Pnv10Chip *chip10 = PNV10_CHIP(dev);
 Error *local_err = NULL;
+int i;
 
 /* XSCOM bridge is first */
 pnv_xscom_realize(chip, PNV10_XSCOM_SIZE, _err);
@@ -1863,6 +1868,28 @@ static void pnv_chip_power10_realize(DeviceState *dev, 
Error **errp)
 error_propagate(errp, local_err);
 return;
 }
+
+
+/*
+ * I2C
+ */
+for (i = 0; i < pcc->i2c_num_engines; i++) {
+Object *obj =  OBJECT(>i2c[i]);
+
+object_property_set_int(obj, "engine", i + 1, _fatal);
+object_property_set_int(obj, "num-busses", pcc->i2c_num_ports,
+_fatal);
+object_property_set_link(obj, "chip", OBJECT(chip), _abort);
+if (!qdev_realize(DEVICE(obj), NULL, errp)) {
+return;
+}
+pnv_xscom_add_subregion(chip, PNV10_XSCOM_I2CM_BASE +
+chip10->i2c[i].engine * PNV10_XSCOM_I2CM_SIZE,
+>i2c[i].xscom_regs);
+qdev_connect_gpio_out(DEVICE(>i2c[i]), 0,
+  qdev_get_gpio_in(DEVICE(>psi),
+   PSIHB9_IRQ_SBE_I2C));
+}
 }
 
 static uint32_t pnv_chip_power10_xscom_pcba(PnvChip *chip, uint64_t addr)
@@ -1890,6 +1917,8 @@ static void pnv_chip_power10_class_init(ObjectClass 
*klass, void *data)
 k->xscom_pcba = pnv_chip_power10_xscom_pcba;
 dc->desc = "PowerNV Chip POWER10";
 k->num_pecs = PNV10_CHIP_MAX_PEC;
+k->i2c_num_engines = PNV10_CHIP_MAX_I2C;
+k->i2c_num_ports = PNV10_CHIP_MAX_I2C_PORTS;
 
 device_class_set_parent_realize(dc, pnv_chip_power10_realize,
 >parent_realize);
diff --git a/include/hw/ppc/pnv_chip.h b/include/hw/ppc/pnv_chip.h
index 90cfbad1a5..5815d96ecf 100644
--- a/include/hw/ppc/pnv_chip.h
+++ b/include/hw/ppc/pnv_chip.h
@@ -120,6 +120,10 @@ struct Pnv10Chip {
 
 #define PNV10_CHIP_MAX_PEC 2
 PnvPhb4PecState pecs[PNV10_CHIP_MAX_PEC];
+
+#define PNV10_CHIP_MAX_I2C 4
+#define PNV10_CHIP_MAX_I2C_PORTS 2
+PnvI2C   i2c[PNV10_CHIP_MAX_I2C];
 };
 
 #define PNV10_PIR2FUSEDCORE(pir) (((pir) >> 3) & 0xf)
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 0c8b873c4c..2b607b22c9 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -152,6 +152,9 @@ struct PnvXScomInterfaceClass {
 #define PNV10_XSCOM_PSIHB_BASE 0x3011D00
 #define PNV10_XSCOM_PSIHB_SIZE 0x100
 
+#define PNV10_XSCOM_I2CM_BASE  PNV9_XSCOM_I2CM_BASE
+#define PNV10_XSCOM_I2CM_SIZE  PNV9_XSCOM_I2CM_SIZE
+
 #define PNV10_XSCOM_OCC_BASE   PNV9_XSCOM_OCC_BASE
 #define PNV10_XSCOM_OCC_SIZE   PNV9_XSCOM_OCC_SIZE
 
-- 
2.31.1




[PATCH v2 0/6] riscv: zicntr/zihpm flags and disable support

2023-10-17 Thread Daniel Henrique Barboza
Hi,

This is a follow-up of the work done in [1] after review comments made
in the rva22u64 profile support review [2].

zicntr and zihpm are already implemented by QEMU before they were added
as discrete extensions by RVI. This puts QEMU in a weird spot because it
has enabled default extensions that aren't togglable on/off via user
flags and aren't reported in riscv,isa as present.

There's no reason to no treat both zicntr and zihpm as regular
extensions, reporting their existence in riscv,isa DT and allowing users
to disable them. This will also benefit us in the incoming profile
support, since disabling a profile should disable all its mandatory
extensions, and for the rva22u64 profile this means that both zicntr and
zihpm should be disabled as well. 

Let's add user flags and disable support for both in all accelerators
(TCG and KVM). FWIW Linux boot doesn't seem to care about the lack of
both zicntr and zihpm when running TCG, although attempting to use the
timers will result in SIGILL.


[1] 
https://lore.kernel.org/qemu-riscv/20230717215419.124258-1-dbarb...@ventanamicro.com/
[2] 
https://lore.kernel.org/qemu-riscv/20231017-e7a4712137165b59844499e3@orel/T/#m3bb0e3c9b00d9edd168da9f7de0bc26df4f7d6ab

Daniel Henrique Barboza (6):
  target/riscv/cpu.c: add zicntr extension flag
  target/riscv/tcg: add ext_zicntr disable support
  target/riscv/kvm: add zicntr reg
  target/riscv/cpu.c: add zihpm extension flag
  target/riscv/tcg: add ext_zihpm disable support
  target/riscv/kvm: add zihpm reg

 target/riscv/cpu.c | 15 +++
 target/riscv/cpu_cfg.h |  2 ++
 target/riscv/csr.c |  4 
 target/riscv/kvm/kvm-cpu.c |  2 ++
 target/riscv/tcg/tcg-cpu.c | 21 +
 5 files changed, 44 insertions(+)

-- 
2.41.0




[PATCH v2 4/6] target/riscv/cpu.c: add zihpm extension flag

2023-10-17 Thread Daniel Henrique Barboza
zihpm is the Hardware Performance Counters extension described in
chapter 12 of the unprivileged spec. It describes support for 29
unprivileged performance counters, hpmcounter3-hpmcounter31.

As with zicntr, QEMU already implements zihpm before it was even an
extension. zihpm is also part of the RVA22 profile, so add it to QEMU
to complement the future profile implementation.

Default it to 'true' for all existing CPUs since it was always present
in the code.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 3 +++
 target/riscv/cpu_cfg.h | 1 +
 2 files changed, 4 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index f478245254..c64cd726f4 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -84,6 +84,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_zifencei),
 ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl),
 ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
+ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_zihpm),
 ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
 ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
 ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
@@ -1185,6 +1186,7 @@ static void riscv_cpu_init(Object *obj)
  * users disable them.
  */
 RISCV_CPU(obj)->cfg.ext_zicntr = true;
+RISCV_CPU(obj)->cfg.ext_zihpm = true;
 }
 
 typedef struct misa_ext_info {
@@ -1274,6 +1276,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
 MULTI_EXT_CFG_BOOL("svpbmt", ext_svpbmt, false),
 
 MULTI_EXT_CFG_BOOL("zicntr", ext_zicntr, true),
+MULTI_EXT_CFG_BOOL("zihpm", ext_zihpm, true),
 
 MULTI_EXT_CFG_BOOL("zba", ext_zba, true),
 MULTI_EXT_CFG_BOOL("zbb", ext_zbb, true),
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 3c91b63609..173bd7d910 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -69,6 +69,7 @@ struct RISCVCPUConfig {
 bool ext_zicond;
 bool ext_zihintntl;
 bool ext_zihintpause;
+bool ext_zihpm;
 bool ext_smstateen;
 bool ext_sstc;
 bool ext_svadu;
-- 
2.41.0




[PATCH v2 1/6] target/riscv/cpu.c: add zicntr extension flag

2023-10-17 Thread Daniel Henrique Barboza
zicntr is the Base Counters and Timers extension described in chapter 12
of the unprivileged spec. It describes support for RDCYCLE, RDTIME and
RDINSTRET.

QEMU already implements it way before it was a discrete extension.
zicntr is part of the RVA22 profile, so let's add it to QEMU to make the
future profile implementation flag complete.

Given than it represents an already existing feature, default it to
'true' for all CPUs. Accelerators are responsible for disabling them if
the user wants to.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 12 
 target/riscv/cpu_cfg.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 2f98ce56e0..f478245254 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -79,6 +79,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_zicbom),
 ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_zicboz),
 ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
+ISA_EXT_DATA_ENTRY(zicntr, PRIV_VERSION_1_12_0, ext_zicntr),
 ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_zicsr),
 ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_zifencei),
 ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl),
@@ -1175,6 +1176,15 @@ static void riscv_cpu_init(Object *obj)
 qdev_init_gpio_in(DEVICE(obj), riscv_cpu_set_irq,
   IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
 #endif /* CONFIG_USER_ONLY */
+
+/*
+ * The timer and performance counters extensions were supported
+ * in QEMU before they were added as discrete extensions in the
+ * ISA. To keep compatibility we'll always default them to 'true'
+ * for all CPUs. Each accelerator will decide what to do when
+ * users disable them.
+ */
+RISCV_CPU(obj)->cfg.ext_zicntr = true;
 }
 
 typedef struct misa_ext_info {
@@ -1263,6 +1273,8 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
 MULTI_EXT_CFG_BOOL("svnapot", ext_svnapot, false),
 MULTI_EXT_CFG_BOOL("svpbmt", ext_svpbmt, false),
 
+MULTI_EXT_CFG_BOOL("zicntr", ext_zicntr, true),
+
 MULTI_EXT_CFG_BOOL("zba", ext_zba, true),
 MULTI_EXT_CFG_BOOL("zbb", ext_zbb, true),
 MULTI_EXT_CFG_BOOL("zbc", ext_zbc, true),
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 208cac1c7c..3c91b63609 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -62,6 +62,7 @@ struct RISCVCPUConfig {
 bool ext_zksh;
 bool ext_zkt;
 bool ext_zifencei;
+bool ext_zicntr;
 bool ext_zicsr;
 bool ext_zicbom;
 bool ext_zicboz;
-- 
2.41.0




[PATCH v2 6/6] target/riscv/kvm: add zihpm reg

2023-10-17 Thread Daniel Henrique Barboza
Add zihpm support in the KVM driver now that QEMU supports it.

This reg was added in Linux 6.6.

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

diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 6c2a92d171..5246fc2bdc 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -217,6 +217,7 @@ static KVMCPUConfig kvm_multi_ext_cfgs[] = {
 KVM_EXT_CFG("zicboz", ext_zicboz, KVM_RISCV_ISA_EXT_ZICBOZ),
 KVM_EXT_CFG("zicntr", ext_zicntr, KVM_RISCV_ISA_EXT_ZICNTR),
 KVM_EXT_CFG("zihintpause", ext_zihintpause, KVM_RISCV_ISA_EXT_ZIHINTPAUSE),
+KVM_EXT_CFG("zihpm", ext_zihpm, KVM_RISCV_ISA_EXT_ZIHPM),
 KVM_EXT_CFG("zbb", ext_zbb, KVM_RISCV_ISA_EXT_ZBB),
 KVM_EXT_CFG("ssaia", ext_ssaia, KVM_RISCV_ISA_EXT_SSAIA),
 KVM_EXT_CFG("sstc", ext_sstc, KVM_RISCV_ISA_EXT_SSTC),
-- 
2.41.0




[PATCH v2 2/6] target/riscv/tcg: add ext_zicntr disable support

2023-10-17 Thread Daniel Henrique Barboza
Support for the zicntr counters are already in place. We need a way to
disable them if the user wants to. This is done by restricting access to
the CYCLE, TIME, and INSTRET counters via the 'ctr()' predicate when
we're about to access them.

Disabling zicntr happens via the command line or if its dependency,
zicsr, happens to be disabled. We'll check for zicsr during realize() and,
in case it's absent, disable zicntr. However, if the user was explicit
about having zicntr support, error out instead of disabling it.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/csr.c | 4 
 target/riscv/tcg/tcg-cpu.c | 8 
 2 files changed, 12 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index a5be1c202c..05c6a69123 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -122,6 +122,10 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 
 if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
 (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
+if (!riscv_cpu_cfg(env)->ext_zicntr) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
 goto skip_ext_pmu_check;
 }
 
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index bbce254ee1..a01b876621 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -541,6 +541,14 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zksh), true);
 }
 
+if (cpu->cfg.ext_zicntr && !cpu->cfg.ext_zicsr) {
+if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zicntr))) {
+error_setg(errp, "zicntr requires zicsr");
+return;
+}
+cpu->cfg.ext_zicntr = false;
+}
+
 /*
  * Disable isa extensions based on priv spec after we
  * validated and set everything we need.
-- 
2.41.0




[PATCH v2 3/6] target/riscv/kvm: add zicntr reg

2023-10-17 Thread Daniel Henrique Barboza
Add zicntr support in the KVM driver now that QEMU supports it.

This reg was added in Linux 6.6.

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

diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 5695f2face..6c2a92d171 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -215,6 +215,7 @@ static void kvm_riscv_update_cpu_misa_ext(RISCVCPU *cpu, 
CPUState *cs)
 static KVMCPUConfig kvm_multi_ext_cfgs[] = {
 KVM_EXT_CFG("zicbom", ext_zicbom, KVM_RISCV_ISA_EXT_ZICBOM),
 KVM_EXT_CFG("zicboz", ext_zicboz, KVM_RISCV_ISA_EXT_ZICBOZ),
+KVM_EXT_CFG("zicntr", ext_zicntr, KVM_RISCV_ISA_EXT_ZICNTR),
 KVM_EXT_CFG("zihintpause", ext_zihintpause, KVM_RISCV_ISA_EXT_ZIHINTPAUSE),
 KVM_EXT_CFG("zbb", ext_zbb, KVM_RISCV_ISA_EXT_ZBB),
 KVM_EXT_CFG("ssaia", ext_ssaia, KVM_RISCV_ISA_EXT_SSAIA),
-- 
2.41.0




[PATCH v2 5/6] target/riscv/tcg: add ext_zihpm disable support

2023-10-17 Thread Daniel Henrique Barboza
Disabling ext_zihpm does nothing at this moment. Add support to disable
the hpmcounter3-hpmcounter31 counters if the user disables zihpm.

There is already code in place in target/riscv/csr.c in all predicates
for these counters (ctr() and mctr()) that disables them if
cpu->cfg.pmu_num is zero. Thus, setting cpu->cfg.pmu_num to zero if
'zihpm=false' is enough to disable the extension.

Set cpu->pmu_avail_ctrs mask to zero as well since this is also checked
to verify if the counters exist.

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

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index a01b876621..7a4400e2ba 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -549,6 +549,19 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 cpu->cfg.ext_zicntr = false;
 }
 
+if (cpu->cfg.ext_zihpm && !cpu->cfg.ext_zicsr) {
+if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zihpm))) {
+error_setg(errp, "zihpm requires zicsr");
+return;
+}
+cpu->cfg.ext_zihpm = false;
+}
+
+if (!cpu->cfg.ext_zihpm) {
+cpu->cfg.pmu_num = 0;
+cpu->pmu_avail_ctrs = 0;
+}
+
 /*
  * Disable isa extensions based on priv spec after we
  * validated and set everything we need.
-- 
2.41.0




Re: [RFC PATCH v2 04/78] qapi/opts-visitor: add fallthrough pseudo-keyword

2023-10-17 Thread Eric Blake
On Fri, Oct 13, 2023 at 10:56:31AM +0300, Emmanouil Pitsidianakis wrote:
> In preparation of raising -Wimplicit-fallthrough to 5, replace all
> fall-through comments with the fallthrough attribute pseudo-keyword.
> 
> Signed-off-by: Emmanouil Pitsidianakis 
> ---
>  qapi/opts-visitor.c | 1 +
>  qapi/string-input-visitor.c | 4 ++--
>  2 files changed, 3 insertions(+), 2 deletions(-)
>

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:  qemu.org | libguestfs.org




Re: [RFC PATCH v2 02/78] block: add fallthrough pseudo-keyword

2023-10-17 Thread Eric Blake
On Fri, Oct 13, 2023 at 10:56:29AM +0300, Emmanouil Pitsidianakis wrote:
> In preparation of raising -Wimplicit-fallthrough to 5, replace all
> fall-through comments with the fallthrough attribute pseudo-keyword.
> 
> Signed-off-by: Emmanouil Pitsidianakis 
> ---
>  block/block-copy.c|  1 +
>  block/file-posix.c|  1 +
>  block/io.c|  1 +
>  block/iscsi.c |  1 +
>  block/qcow2-cluster.c |  5 -
>  block/vhdx.c  | 17 +
>  6 files changed, 21 insertions(+), 5 deletions(-)
> 
> diff --git a/block/block-copy.c b/block/block-copy.c
> index 1c60368d72..b4ceb6a079 100644
> --- a/block/block-copy.c
> +++ b/block/block-copy.c
...
>  case COPY_RANGE_FULL:
>  ret = bdrv_co_copy_range(s->source, offset, s->target, offset, 
> nbytes,
>   0, s->write_flags);
>  if (ret >= 0) {
>  /* Successful copy-range, increase chunk size.  */
>  *method = COPY_RANGE_FULL;
>  return 0;
>  }
>  
>  trace_block_copy_copy_range_fail(s, offset, ret);
>  *method = COPY_READ_WRITE;
>  /* Fall through to read+write with allocated buffer */
> +fallthrough;
>  
>  case COPY_READ_WRITE_CLUSTER:
>  case COPY_READ_WRITE:

I like how you kept the comments.

> +++ b/block/qcow2-cluster.c
> @@ -1327,36 +1327,39 @@ static int coroutine_fn 
> calculate_l2_meta(BlockDriverState *bs,
>  /*
>   * Returns true if writing to the cluster pointed to by @l2_entry
>   * requires a new allocation (that is, if the cluster is unallocated
>   * or has refcount > 1 and therefore cannot be written in-place).
>   */
>  static bool cluster_needs_new_alloc(BlockDriverState *bs, uint64_t l2_entry)
>  {
>  switch (qcow2_get_cluster_type(bs, l2_entry)) {
>  case QCOW2_CLUSTER_NORMAL:
> +fallthrough;
>  case QCOW2_CLUSTER_ZERO_ALLOC:

Why is this one needed?  It looks two case labels for the same code is
okay; the fallthrough attribute is only needed once a case label is no
lonter empty.

>  if (l2_entry & QCOW_OFLAG_COPIED) {
>  return false;
>  }
> -/* fallthrough */
> +fallthrough;

This one makes sense.

>  case QCOW2_CLUSTER_UNALLOCATED:
> +fallthrough;
>  case QCOW2_CLUSTER_COMPRESSED:
> +fallthrough;

These two also look spurious.

>  case QCOW2_CLUSTER_ZERO_PLAIN:
>  return true;
>  default:
>  abort();
>  }
>  }
...
> +++ b/block/vhdx.c
> @@ -1176,60 +1176,65 @@ static int coroutine_fn GRAPH_RDLOCK
>  vhdx_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
>QEMUIOVector *qiov)
...
>  /* check the payload block state */
>  switch (s->bat[sinfo.bat_idx] & VHDX_BAT_STATE_BIT_MASK) {
> -case PAYLOAD_BLOCK_NOT_PRESENT: /* fall through */
> +case PAYLOAD_BLOCK_NOT_PRESENT:
> +fallthrough;
>  case PAYLOAD_BLOCK_UNDEFINED:
> +fallthrough;
>  case PAYLOAD_BLOCK_UNMAPPED:
> +fallthrough;
>  case PAYLOAD_BLOCK_UNMAPPED_v095:
> +fallthrough;

All four of these look spurious; although the old comment is also
spurious, so I'd be happy with deleting it without replacement.

>  case PAYLOAD_BLOCK_ZERO:
>  /* return zero */
>  qemu_iovec_memset(_qiov, 0, 0, sinfo.bytes_avail);
>  break;
>  case PAYLOAD_BLOCK_FULLY_PRESENT:
>  qemu_co_mutex_unlock(>lock);
>  ret = bdrv_co_preadv(bs->file, sinfo.file_offset,
>   sinfo.sectors_avail * BDRV_SECTOR_SIZE,
>   _qiov, 0);
>  qemu_co_mutex_lock(>lock);
>  if (ret < 0) {
>  goto exit;
>  }
>  break;
>  case PAYLOAD_BLOCK_PARTIALLY_PRESENT:
>  /* we don't yet support difference files, fall through
>   * to error */
> +fallthrough;
>  default:

But keeping this one because of the comment is reasonable.

...
>  switch (bat_state) {
>  case PAYLOAD_BLOCK_ZERO:
>  /* in this case, we need to preserve zero writes for
>   * data that is not part of this write, so we must pad
>   * the rest of the buffer to zeroes */
>  use_zero_buffers = true;
> -/* fall through */
> -case PAYLOAD_BLOCK_NOT_PRESENT: /* fall through */
> +fallthrough;
> +case PAYLOAD_BLOCK_NOT_PRESENT:

This one is necessary;

> +fallthrough;
>  case PAYLOAD_BLOCK_UNMAPPED:
> +fallthrough;
>  case PAYLOAD_BLOCK_UNMAPPED_v095:
> +fallthrough;
>  case 

Re: [RFC PATCH v2 01/78] include/qemu/compiler.h: replace QEMU_FALLTHROUGH with fallthrough

2023-10-17 Thread Eric Blake
On Fri, Oct 13, 2023 at 10:56:28AM +0300, Emmanouil Pitsidianakis wrote:
> Signed-off-by: Emmanouil Pitsidianakis 

The subject line gives the 'what', but the commit body is
conspicuously lacking on the 'why'.

> ---
>  audio/pwaudio.c  |  8 
>  hw/arm/smmuv3.c  |  2 +-
>  include/qemu/compiler.h  | 30 +++---
>  include/qemu/osdep.h |  4 ++--
>  target/loongarch/cpu.c   |  4 ++--
>  target/loongarch/translate.c |  2 +-
>  tcg/optimize.c   |  8 
>  7 files changed, 37 insertions(+), 21 deletions(-)
> 
> diff --git a/audio/pwaudio.c b/audio/pwaudio.c
> index 3ce5f6507b..bf26fadb06 100644
> --- a/audio/pwaudio.c
> +++ b/audio/pwaudio.c
> @@ -1,29 +1,29 @@
>  /*
>   * QEMU PipeWire audio driver
>   *
>   * Copyright (c) 2023 Red Hat Inc.
>   *
>   * Author: Dorinda Bassey   
>   *
>   * SPDX-License-Identifier: GPL-2.0-or-later
>   */
>  
> +#include 
> +#include 
> +#include 
> +#include 
>  #include "qemu/osdep.h"
>  #include "qemu/module.h"
>  #include "audio.h"
>  #include 
>  #include "qemu/error-report.h"
>  #include "qapi/error.h"
> -#include 
> -#include 
> -#include 
> -#include 

Rearranging #includes should be called out in the commit message, or
even better split into its own commit as it is distinct from renaming
the fallthrough macro.

>  
>  #include 
>  #include "trace.h"
>  
>  #define AUDIO_CAP "pipewire"
>  #define RINGBUFFER_SIZE(1u << 22)
>  #define RINGBUFFER_MASK(RINGBUFFER_SIZE - 1)
>  
>  #include "audio_int.h"
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index 6f2b2bd45f..545d82ff04 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -1166,210 +1166,210 @@ smmuv3_invalidate_ste(gpointer key, gpointer value, 
> gpointer user_data)

Wow, your git settings picked up a LOT of context - makes for a longer
email, but in this particular case, it IS nice to see the impact of
the fallthrough by seeing the full switch statment.

...
>  qemu_mutex_lock(>mutex);
>  switch (type) {
>  case SMMU_CMD_SYNC:
...
>  case SMMU_CMD_TLBI_NH_ALL:
>  if (!STAGE1_SUPPORTED(s)) {
>  cmd_error = SMMU_CERROR_ILL;
>  break;
>  }
> -QEMU_FALLTHROUGH;
> +fallthrough;
>  case SMMU_CMD_TLBI_NSNH_ALL:

Yes, that still looks legible to me.

> +++ b/include/qemu/compiler.h
> @@ -1,215 +1,231 @@
...
>  #if defined(__OPTIMIZE__)
>  #define QEMU_ALWAYS_INLINE  __attribute__((always_inline))
>  #else
>  #define QEMU_ALWAYS_INLINE
>  #endif
>  
> -/**
> - * In most cases, normal "fallthrough" comments are good enough for
> - * switch-case statements, but sometimes the compiler has problems
> - * with those. In that case you can use QEMU_FALLTHROUGH instead.
> +/*
> + * Add the pseudo keyword 'fallthrough' so case statement blocks
> + * must end with any of these keywords:
> + *   break;
> + *   fallthrough;
> + *   continue;
> + *   goto ;
> + *   return [expression];
> + *
> + *  gcc: 
> https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#Statement-Attributes
>   */
> -#if __has_attribute(fallthrough)
> -# define QEMU_FALLTHROUGH __attribute__((fallthrough))
> +
> +/*
> + * glib_macros.h contains its own definition of fallthrough, so if we define
> + * the pseudokeyword here it will expand when the glib header checks for the
> + * attribute. glib headers must be #included after this header.
> + */
> +#ifdef fallthrough
> +#undef fallthrough
> +#endif
> +
> +#if __has_attribute(__fallthrough__)
> +# define fallthrough__attribute__((__fallthrough__))
>  #else
> -# define QEMU_FALLTHROUGH do {} while (0) /* fallthrough */
> +# define fallthroughdo {} while (0)  /* fallthrough */
>  #endif
>

Looks okay.

> +++ b/include/qemu/osdep.h
> @@ -1,171 +1,171 @@
>  /*
>   * TARGET_WORDS_BIGENDIAN was replaced with TARGET_BIG_ENDIAN. Prevent it 
> from
>   * creeping back in.
>   */
>  #pragma GCC poison TARGET_WORDS_BIGENDIAN
>  
> -#include "qemu/compiler.h"
> -
>  /* Older versions of C++ don't get definitions of various macros from
>   * stdlib.h unless we define these macros before first inclusion of
>   * that system header.
>   */
...
>  /*
>   * This is somewhat like a system header; it must be outside any extern "C"
>   * block because it includes system headers itself, including glib.h,
>   * which will not compile if inside an extern "C" block.
>   */
>  #include "glib-compat.h"
>  
> +#include "qemu/compiler.h"
> +

The commit message should detail why we had to sink this include
later, and any audit you did to ensure that none of the intermediate
code is impacted by that change.

At this point, since the series is RFC, I'll leave merely:

Acked-by: Eric Blake 

but if others like the approach, I'll probably replace it with R-b in
the next version.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:  qemu.org | 

Re: [RFC PATCH v2 00/78] Strict disable implicit fallthrough

2023-10-17 Thread Eric Blake
On Fri, Oct 13, 2023 at 10:56:27AM +0300, Emmanouil Pitsidianakis wrote:
> /* resubmitted because git-send-email crashed with previous attempt */
> 
> Hello,
> 
> This RFC is inspired by the kernel's move to -Wimplicit-fallthrough=3
> back in 2019.[0]
> We take one step (or two) further by increasing it to 5 which rejects
> fall through comments and requires an attribute statement.
> 
> [0]:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a035d552a93b
> 
> The line differences are not many, but they spread all over different
> subsystems, architectures and devices. An attempt has been made to split
> them in cohesive patches to aid post-RFC review. Part of the RFC is to
> determine whether these patch divisions needs improvement.
> 
> Main questions this RFC poses
> =
> 
> - Is this change desirable and net-positive.

I think so - consistency eases code maintenance, and being able to
define a keyword-like macro used like any other control-flow statement
is nicer than a magic comment.

> - Should the `fallthrough;` pseudo-keyword be defined like in the Linux
>   kernel, or use glib's G_GNUC_FALLTHROUGH, or keep the already existing
>   QEMU_FALLTHROUGH macro.

This seems like it only affects the one place where we define the
keyword.  As long as all switch statements actually using it stick to
one style, I'm less concerned about the magic used to get the style
working in the first place.

> - Should fallthrough comments be removed if they do not include extra
>   information.

That would be fine by me - but we'll see what other reviewers say.
I'm going to review on just the files I normally touch.

> 
> Some external resources
> ===
> 
> See the RFC discussion in the kernel:
> 
> https://lore.kernel.org/lkml/1d2830aadbe9d8151728a7df5b88528fc72a0095.1564549413.git@perches.com/
> 
> The `fallthrough;` pseudo-keyword in the kernel source code:
> 
> https://elixir.bootlin.com/linux/latest/C/ident/fallthrough
> 
> In summary, I quote the doc comment and definition:
> 
> /*
>  * Add the pseudo keyword 'fallthrough' so case statement blocks
>  * must end with any of these keywords:
>  *   break;
>  *   fallthrough;
>  *   continue;
>  *   goto ;
>  *   return [expression];
>  *
>  *  gcc: 
> https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#Statement-Attributes
>  */
> #if __has_attribute(__fallthrough__)
> # define fallthrough__attribute__((__fallthrough__))
> #else
> # define fallthroughdo {} while (0)  /* fallthrough */
> #endif
> 
> Background - Motivation
> ===
> 
> The C switch statement allows you to conditionally goto different labels
> depending on a value. A break; statement conveniently goto's the end of
> the switch. If a "case" does not end in a break, we say that the control
> flow falls through the next case label, if any, implicitly. This can
> lead to bugs and QEMU uses the GCC warning -Wimplicit-fallthrough to
> prevent this.
> 
> Currently, QEMU is built with -Wimplicit-fallthrough=2. This makes GCC's
> static analyzer check for a case-insensitive matches of the .*falls?[
> \t-]*thr(ough|u).* regular expression. This means the following list of
> comments taken from QEMU all disable the implicit fallthrough warning:
> 
> - /* FALLTHRU */
> - /* fall through */
> - /* Fall through.  */
> - /* Fall through... */
> - /* fall through if hEventTimeout is signaled */
> - /* FALL THROUGH */
> 
> To keep a constistent code style, this commit adds a macro `fallthrough`
> that looks like a C keyword but expands to an attribute statement in
> supported compilers (GCC at the moment).
> 
> Note: there was already such a macro, QEMU_FALLTHROUGH, and it was used
> only around 7 times in the code base. The first commit replaces it.

Seems reasonable to me; we'll see what other comments you get.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:  qemu.org | libguestfs.org




Re: [PATCH v2 1/3] via-ide: Fix legacy mode emulation

2023-10-17 Thread BALATON Zoltan

On Tue, 17 Oct 2023, Mark Cave-Ayland wrote:

On 16/10/2023 23:16, BALATON Zoltan wrote:

On Sun, 15 Oct 2023, Mark Cave-Ayland wrote:

On 14/10/2023 17:13, BALATON Zoltan wrote:

On Sat, 14 Oct 2023, Mark Cave-Ayland wrote:
Using the portio_list*() APIs really is the right way to implement this 
to avoid being affected by such issues.


Can you provide an alternative patch using portio_list? I don't know how 
to do that and have no example to follow either so it would be hard for 
me to figure out. Or give some pointers on how to do this if I missed 
something.


Here's a hacked up version based upon various bits and pieces from my WIP 
IDE mode switching branch. It's briefly compile tested, and checked with 
"info mtree" and a couple of test boots:



I gave this a try and while it works with the guests I've tried I'm still 
not convinced. See comments below.


Okay, that's good news and proves the basic concept works as expected.


Well it works but seems much more hacky and complex at the moment than my 
patch which also not perfect but works as well and solves the problem with 
much less change so I still don't like this patch of yours too much. But 
if you can clean it in time before the freeze so this won't cause my other 
patches depending on this missing the release I'm OK with this alternative 
approach even if I think it's not necessary and could be done any time 
later. My patch does not prevent you to take this futther and do this 
later, but you not allowing my patch and then not providing alternative in 
time for the series to be merged would make me not able to progress with 
this machine model and prevent users start using it.



diff --git a/hw/ide/via.c b/hw/ide/via.c
index fff23803a6..82f2af1c78 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -28,12 +28,27 @@
#include "hw/pci/pci.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
+#include "qemu/range.h"
#include "sysemu/dma.h"
#include "hw/isa/vt82c686.h"
#include "hw/ide/pci.h"
#include "hw/irq.h"
#include "trace.h"

+
+/* FIXME: export these from hw/ide/ioport.c */
+static const MemoryRegionPortio ide_portio_list[] = {
+    { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write },
+    { 0, 1, 2, .read = ide_data_readw, .write = ide_data_writew },
+    { 0, 1, 4, .read = ide_data_readl, .write = ide_data_writel },
+    PORTIO_END_OF_LIST(),
+};
+
+static const MemoryRegionPortio ide_portio2_list[] = {
+    { 0, 1, 1, .read = ide_status_read, .write = ide_ctrl_write },
+    PORTIO_END_OF_LIST(),
+};
+
static uint64_t bmdma_read(void *opaque, hwaddr addr,
   unsigned size)
{
@@ -137,7 +152,10 @@ static void via_ide_reset(DeviceState *dev)
    pci_set_long(pci_conf + PCI_BASE_ADDRESS_2, 0x0170);
    pci_set_long(pci_conf + PCI_BASE_ADDRESS_3, 0x0374);
    pci_set_long(pci_conf + PCI_BASE_ADDRESS_4, 0xcc01); /* BMIBA: 
20-23h */

-    pci_set_long(pci_conf + PCI_INTERRUPT_LINE, 0x010e);
+    pci_set_long(pci_conf + PCI_INTERRUPT_LINE, 0x000e);


The vt8231 data sheet says the interrupt pin should always be 1 while 
according to the vt82c686b data sheet this means legacy or native interrupt 
routing and defaults to 0. We probably don't do anything with it so no 
matter what we have here and we can change it to 0 but maybe there's 
someting off here in any case.


According to the VT8231 datasheet I have here, the interrupt pin register is 
read-only but defaults to zero. But then that's fine because that is the 
expected value in legacy mode which is what you would expect with a default 
PCI_CLASS_PROG set to 0x8a.


According to the data sheet I have (VT8231 South Bridge Revision 2.32, 
September 1, 2004) IDE func config reg 0x3d Interrupt Pin defaults to 01. 
Maybe you're looking at an even more buggy preliminary data sheet that I 
think Bernhard had before too. But it probably does not matter what's in 
this reg anyway so this is a small detail.



+
+    /* Clear subsystem to match real hardware */
+    pci_set_long(pci_conf + 0x2c, 0x0);

    /* IDE chip enable, IDE configuration 1/2, IDE FIFO Configuration*/
    pci_set_long(pci_conf + 0x40, 0x0a090600);
@@ -159,6 +177,89 @@ static void via_ide_reset(DeviceState *dev)
    pci_set_long(pci_conf + 0xc0, 0x00020001);
}

+static void via_ide_cfg_write(PCIDevice *pd, uint32_t addr,
+  uint32_t val, int len)
+{
+    uint8_t *pci_conf = pd->config;
+    PCIIDEState *d = PCI_IDE(pd);
+
+    pci_default_write_config(pd, addr, val, len);
+
+    if (range_covers_byte(addr, len, PCI_CLASS_PROG)) {
+    if (pci_conf[PCI_CLASS_PROG] == 0x8a) {
+    /* FIXME: don't disable BARs
+    pci_default_write_config(pd, PCI_BASE_ADDRESS_0, 0x1, 4);
+    pci_default_write_config(pd, PCI_BASE_ADDRESS_1, 0x1, 4);
+    pci_default_write_config(pd, PCI_BASE_ADDRESS_2, 0x1, 4);
+    pci_default_write_config(pd, PCI_BASE_ADDRESS_3, 0x1, 4);
+    */
+
+    

Re: [PATCH v2] intel-iommu: Report interrupt remapping faults, fix return value

2023-10-17 Thread David Woodhouse
On Tue, 2023-10-17 at 17:28 -0400, Michael S. Tsirkin wrote:
> On Tue, Oct 17, 2023 at 10:19:55PM +0100, David Woodhouse wrote:
> > On Wed, 2023-08-23 at 11:37 -0400, Peter Xu wrote:
> > > On Wed, Aug 23, 2023 at 01:23:25PM +0100, David Woodhouse wrote:
> > > > From: David Woodhouse 
> > > > 
> > > > A generic X86IOMMUClass->int_remap function should not return VT-d
> > > > specific values; fix it to return 0 if the interrupt was successfully
> > > > translated or -EINVAL if not.
> > > > 
> > > > The VTD_FR_IR_xxx values are supposed to be used to actually raise
> > > > faults through the fault reporting mechanism, so do that instead for
> > > > the case where the IRQ is actually being injected.
> > > > 
> > > > There is more work to be done here, as pretranslations for the KVM IRQ
> > > > routing table can't fault; an untranslatable IRQ should be handled in
> > > > userspace and the fault raised only when the IRQ actually happens (if
> > > > indeed the IRTE is still not valid at that time). But we can work on
> > > > that later; we can at least raise faults for the direct case.
> > > > 
> > > > Signed-off-by: David Woodhouse 
> > > 
> > > Acked-by: Peter Xu 
> > 
> > Thanks.
> > 
> > What do I do with this next? It's still lurking in my working tree.
> > 
> > 
> 
> Not sure how I lost it. Sorry. Will pick up.

I think I just posted it at the wrong time of the release cycle.
Thanks.



smime.p7s
Description: S/MIME cryptographic signature


Re: [PATCH v2] intel-iommu: Report interrupt remapping faults, fix return value

2023-10-17 Thread Michael S. Tsirkin
On Tue, Oct 17, 2023 at 10:19:55PM +0100, David Woodhouse wrote:
> On Wed, 2023-08-23 at 11:37 -0400, Peter Xu wrote:
> > On Wed, Aug 23, 2023 at 01:23:25PM +0100, David Woodhouse wrote:
> > > From: David Woodhouse 
> > > 
> > > A generic X86IOMMUClass->int_remap function should not return VT-d
> > > specific values; fix it to return 0 if the interrupt was successfully
> > > translated or -EINVAL if not.
> > > 
> > > The VTD_FR_IR_xxx values are supposed to be used to actually raise
> > > faults through the fault reporting mechanism, so do that instead for
> > > the case where the IRQ is actually being injected.
> > > 
> > > There is more work to be done here, as pretranslations for the KVM IRQ
> > > routing table can't fault; an untranslatable IRQ should be handled in
> > > userspace and the fault raised only when the IRQ actually happens (if
> > > indeed the IRTE is still not valid at that time). But we can work on
> > > that later; we can at least raise faults for the direct case.
> > > 
> > > Signed-off-by: David Woodhouse 
> > 
> > Acked-by: Peter Xu 
> 
> Thanks.
> 
> What do I do with this next? It's still lurking in my working tree.
> 
> 

Not sure how I lost it. Sorry. Will pick up.




Re: [RFC PATCH] hw/timer/hpet: fix IRQ routing in legacy support mode

2023-10-17 Thread David Woodhouse
On Wed, 2023-08-30 at 21:20 +0100, David Woodhouse wrote:
> From: David Woodhouse 
> 
> The interrupt from timer 0 in legacy mode is supposed to go to IRQ 0 on
> the i8259 and IRQ 2 on the I/O APIC. The generic x86 GSI handling can't
> cope with IRQ numbers differing between the two chips (despite it also
> being the case for PCI INTx routing), so add a special case for the HPET.
> 
> IRQ 2 isn't valid on the i8259; it's the cascade IRQ and would be
> interpreted as spurious interrupt on the secondary PIC. So we can fix
> up all attempts to deliver IRQ2, to actually deliver to IRQ0 on the PIC.
> 
> Signed-off-by: David Woodhouse 
> ---
> It ain't ever so pretty, but it's prettier than the INTx routing hack
> that I just documented and at least this one doesn't rely on guest
> behaviour.


I haven't come up with a better way of doing it, and nobody seemed to
care. Shall I post an identical patch without the [RFC] to see if it
elicits more of a response?

> 
> Do we have tests for HPET interrupt delivery that can be extended to
> cover this?
> 
> 
>  hw/i386/x86.c   | 19 +++
>  hw/timer/hpet.c |  5 -
>  2 files changed, 19 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/i386/x86.c b/hw/i386/x86.c
> index a88a126123..0d2c74f2d9 100644
> --- a/hw/i386/x86.c
> +++ b/hw/i386/x86.c
> @@ -602,13 +602,24 @@ DeviceState *cpu_get_current_apic(void)
>  void gsi_handler(void *opaque, int n, int level)
>  {
>  GSIState *s = opaque;
> -
> +    int i8259_pin = n;
>  trace_x86_gsi_interrupt(n, level);
>  switch (n) {
> -    case 0 ... ISA_NUM_IRQS - 1:
> -    if (s->i8259_irq[n]) {
> +    case 2:
> +    /*
> + * Special case for HPET legacy mode, which is defined as routing 
> HPET
> + * timer 0 to IRQ2 of the I/O APIC and IRQ0 of the i8259 PIC. Since
> + * IRQ2 on the i8259 is the cascade, it isn't otherwise valid so we
> + * handle it via this special case.
> + */
> +    i8259_pin = 0;
> +    /* fall through */
> +    case 0:
> +    case 1:
> +    case 3 ... ISA_NUM_IRQS - 1:
> +    if (s->i8259_irq[i8259_pin]) {
>  /* Under KVM, Kernel will forward to both PIC and IOAPIC */
> -    qemu_set_irq(s->i8259_irq[n], level);
> +    qemu_set_irq(s->i8259_irq[i8259_pin], level);
>  }
>  /* fall through */
>  case ISA_NUM_IRQS ... IOAPIC_NUM_PINS - 1:
> diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
> index 6998094233..9f740ffdee 100644
> --- a/hw/timer/hpet.c
> +++ b/hw/timer/hpet.c
> @@ -196,8 +196,11 @@ static void update_irq(struct HPETTimer *timer, int set)
>  /* if LegacyReplacementRoute bit is set, HPET specification requires
>   * timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC,
>   * timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC.
> + *
> + * There is a special case in the x86 gsi_handler() which converts
> + * IRQ2 into IRQ0 for the i8259 PIC and makes this work correctly.
>   */
> -    route = (timer->tn == 0) ? 0 : RTC_ISA_IRQ;
> +    route = (timer->tn == 0) ? 2 : RTC_ISA_IRQ;
>  } else {
>  route = timer_int_route(timer);
>  }



smime.p7s
Description: S/MIME cryptographic signature


Re: [PATCH v2] intel-iommu: Report interrupt remapping faults, fix return value

2023-10-17 Thread David Woodhouse
On Wed, 2023-08-23 at 11:37 -0400, Peter Xu wrote:
> On Wed, Aug 23, 2023 at 01:23:25PM +0100, David Woodhouse wrote:
> > From: David Woodhouse 
> > 
> > A generic X86IOMMUClass->int_remap function should not return VT-d
> > specific values; fix it to return 0 if the interrupt was successfully
> > translated or -EINVAL if not.
> > 
> > The VTD_FR_IR_xxx values are supposed to be used to actually raise
> > faults through the fault reporting mechanism, so do that instead for
> > the case where the IRQ is actually being injected.
> > 
> > There is more work to be done here, as pretranslations for the KVM IRQ
> > routing table can't fault; an untranslatable IRQ should be handled in
> > userspace and the fault raised only when the IRQ actually happens (if
> > indeed the IRTE is still not valid at that time). But we can work on
> > that later; we can at least raise faults for the direct case.
> > 
> > Signed-off-by: David Woodhouse 
> 
> Acked-by: Peter Xu 

Thanks.

What do I do with this next? It's still lurking in my working tree.




smime.p7s
Description: S/MIME cryptographic signature


Re: [PATCH v2 00/90] target/sparc: Convert to decodetree

2023-10-17 Thread Mark Cave-Ayland

On 17/10/2023 07:11, Richard Henderson wrote:


While doing some other testing the other day, I noticed my sparc64
chroot running particularly slowly.  I think I know what the problem
is there, but fixing that was going to be particularly ugly with the
existing sparc translator.

So I've converted the translator to something more managable.  :-)

Changes for v2:
   * Fixes for JMPL, RETT, SAVE and RESTORE.
   * Fixes for FMOV etc, which had lost gen_op_clear_ieee_excp_and_FTT.
   * Allow conditional exceptions to be raised out of line
 Use this for gen_check_align and conditional trap.
   * Keep properties and feature bits in sync.

r~

Richard Henderson (90):
   target/sparc: Clear may_lookup for npc == DYNAMIC_PC
   target/sparc: Implement check_align inline
   target/sparc: Avoid helper_raise_exception in helper_st_asi
   target/sparc: Set TCG_GUEST_DEFAULT_MO
   configs: Enable MTTCG for sparc, sparc64
   target/sparc: Define features via cpu-feature.h.inc
   target/sparc: Use CPU_FEATURE_BIT_* for cpu properties
   target/sparc: Remove sparcv7 cpu features
   target/sparc: Add decodetree infrastructure
   target/sparc: Define AM_CHECK for sparc32
   target/sparc: Move CALL to decodetree
   target/sparc: Move BPcc and Bicc to decodetree
   target/sparc: Move BPr to decodetree
   target/sparc: Move FBPfcc and FBfcc to decodetree
   target/sparc: Merge gen_cond with only caller
   target/sparc: Merge gen_fcond with only caller
   target/sparc: Merge gen_branch_[an] with only caller
   target/sparc: Pass DisasCompare to advance_jump_cond
   target/sparc: Move SETHI to decodetree
   target/sparc: Move Tcc to decodetree
   target/sparc: Move RDASR, STBAR, MEMBAR to decodetree
   target/sparc: Move RDPSR, RDHPR to decodetree
   target/sparc: Move RDWIM, RDPR to decodetree
   target/sparc: Move RDTBR, FLUSHW to decodetree
   target/sparc: Move WRASR to decodetree
   target/sparc: Move WRPSR, SAVED, RESTORED to decodetree
   target/sparc: Move WRWIM, WRPR to decodetree
   target/sparc: Move WRTBR, WRHPR to decodetree
   target/sparc: Move basic arithmetic to decodetree
   target/sparc: Move ADDC to decodetree
   target/sparc: Move MULX to decodetree
   target/sparc: Move UMUL, SMUL to decodetree
   target/sparc: Move SUBC to decodetree
   target/sparc: Move UDIVX, SDIVX to decodetree
   target/sparc: Move UDIV, SDIV to decodetree
   target/sparc: Move TADD, TSUB, MULS to decodetree
   target/sparc: Move SLL, SRL, SRA to decodetree
   target/sparc: Move MOVcc, MOVR to decodetree
   target/sparc: Move POPC to decodetree
   target/sparc: Convert remaining v8 coproc insns to decodetree
   target/sparc: Move JMPL, RETT, RETURN to decodetree
   target/sparc: Move FLUSH, SAVE, RESTORE to decodetree
   target/sparc: Move DONE, RETRY to decodetree
   target/sparc: Split out resolve_asi
   target/sparc: Drop ifdef around get_asi and friends
   target/sparc: Split out ldst functions with asi pre-computed
   target/sparc: Use tcg_gen_qemu_{ld,st}_i128 for GET_ASI_DTWINX
   target/sparc: Move simple integer load/store to decodetree
   target/sparc: Move asi integer load/store to decodetree
   target/sparc: Move LDSTUB, LDSTUBA to decodetree
   target/sparc: Move SWAP, SWAPA to decodetree
   target/sparc: Move CASA, CASXA to decodetree
   target/sparc: Move PREFETCH, PREFETCHA to decodetree
   target/sparc: Split out fp ldst functions with asi precomputed
   target/sparc: Move simple fp load/store to decodetree
   target/sparc: Move asi fp load/store to decodetree
   target/sparc: Move LDFSR, STFSR to decodetree
   target/sparc: Merge LDFSR, LDXFSR implementations
   target/sparc: Move EDGE* to decodetree
   target/sparc: Move ARRAY* to decodetree
   target/sparc: Move ADDRALIGN* to decodetree
   target/sparc: Move BMASK to decodetree
   target/sparc: Move FMOVS, FNEGS, FABSS, FSRC*S, FNOT*S to decodetree
   target/sparc: Move FMOVD, FNEGD, FABSD, FSRC*D, FNOT*D to decodetree
   target/sparc: Use tcg_gen_vec_{add,sub}*
   target/sparc: Move gen_ne_fop_FFF insns to decodetree
   target/sparc: Move gen_ne_fop_DDD insns to decodetree
   target/sparc: Move PDIST to decodetree
   target/sparc: Move gen_gsr_fop_DDD insns to decodetree
   target/sparc: Move gen_fop_FF insns to decodetree
   target/sparc: Move gen_fop_DD insns to decodetree
   target/sparc: Move FSQRTq to decodetree
   target/sparc: Move gen_fop_FFF insns to decodetree
   target/sparc: Move gen_fop_DDD insns to decodetree
   target/sparc: Move gen_fop_QQQ insns to decodetree
   target/sparc: Move FSMULD to decodetree
   target/sparc: Move FDMULQ to decodetree
   target/sparc: Move gen_fop_FD insns to decodetree
   target/sparc: Move FiTOd, FsTOd, FsTOx to decodetree
   target/sparc: Move FqTOs, FqTOi to decodetree
   target/sparc: Move FqTOd, FqTOx to decodetree
   target/sparc: Move FiTOq, FsTOq to decodetree
   target/sparc: Move FdTOq, FxTOq to decodetree
   target/sparc: Move FMOVq, FNEGq, FABSq to decodetree
   target/sparc: Move FMOVR, FMOVcc, FMOVfcc 

Re: [PATCH v6 3/5] migration: migrate 'blk' command option is deprecated.

2023-10-17 Thread Juan Quintela
Juan Quintela  wrote:
> Use blocked-mirror with NBD instead.
>
> Signed-off-by: Juan Quintela 
> Acked-by: Stefan Hajnoczi 
> Reviewed-by: Thomas Huth 
> Reviewed-by: Markus Armbruster 

Hi Kevin and Stefan

Can we change the iotest output to fix this?

https://gitlab.com/juan.quintela/qemu/-/jobs/5314070229

tput mismatch (see 
/builds/juan.quintela/qemu/build/tests/qemu-iotests/scratch/raw-file-183/183.out.bad)
--- /builds/juan.quintela/qemu/tests/qemu-iotests/183.out
+++ 
/builds/juan.quintela/qemu/build/tests/qemu-iotests/scratch/raw-file-183/183.out.bad
@@ -28,6 +28,8 @@
 { 'execute': 'migrate',
'arguments': { 'uri': 'unix:SOCK_DIR/migrate', 'blk': true } }
+warning: parameter 'blk is deprecated; use blockdev-mirror with NBD instead
+warning: block migration is deprecated; use blockdev-mirror with NBD instead
 {"return": {}}
 { 'execute': 'query-status' }
 {"return": {"status": "postmigrate", "singlestep": false, "running":
 false}}


I really want to give the warnings two users.

I guess that you want to test blk migration.

What do you recommend?

Later, Juan.






Re: [PATCH v3 0/2] Add PowerNV I2C Controller Model

2023-10-17 Thread Miles Glenn
On Tue, 2023-10-17 at 09:01 +0200, Cédric Le Goater wrote:
> On 10/17/23 00:20, Glenn Miles wrote:
> > Upstreams the PowerNV I2C controller model originally
> > authored by Cédric Le Goater with minor changes by
> > myself to split the actual addition of the model from
> > wiring it up to a power processor model.
> > 
> > This series only attaches the controller to the powernv9
> > chip model, but is expected to eventually also be attached
> > to the powernv10 chip model.
> > 
> > Cédric Le Goater (2):
> >ppc/pnv: Add an I2C controller model
> >ppc/pnv: Connect I2C controller model to powernv9 chip
> 
> Reviewed-by: Cédric Le Goater 
> 
> Thanks for taking care of upstreaming Glenn. Waiting for the P10 part
> now !
> 
> C.

No problem!  Thanks for all of your help as well.

Glenn

> 
> 
> >   hw/ppc/meson.build |   1 +
> >   hw/ppc/pnv.c   |  28 ++
> >   hw/ppc/pnv_i2c.c   | 697
> > +
> >   include/hw/ppc/pnv_chip.h  |   8 +
> >   include/hw/ppc/pnv_i2c.h   |  38 ++
> >   include/hw/ppc/pnv_xscom.h |   3 +
> >   6 files changed, 775 insertions(+)
> >   create mode 100644 hw/ppc/pnv_i2c.c
> >   create mode 100644 include/hw/ppc/pnv_i2c.h
> > 




Re: [PATCH v2 02/11] pci_ids/tulip: Add PCI vendor ID for HP and use it in tulip

2023-10-17 Thread Helge Deller

On 10/17/23 22:21, BALATON Zoltan wrote:

On Tue, 17 Oct 2023, Helge Deller wrote:

On 10/17/23 21:19, BALATON Zoltan wrote:

On Tue, 17 Oct 2023, Helge Deller wrote:

On 10/17/23 18:13, BALATON Zoltan wrote:

On Tue, 17 Oct 2023, del...@kernel.org wrote:

From: Helge Deller 

Signed-off-by: Helge Deller 
---
hw/net/tulip.c   | 2 +-
include/hw/pci/pci_ids.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/net/tulip.c b/hw/net/tulip.c
index 915e5fb595..11d866e431 100644
--- a/hw/net/tulip.c
+++ b/hw/net/tulip.c
@@ -1020,7 +1020,7 @@ static void tulip_class_init(ObjectClass *klass, void 
*data)
    k->exit = pci_tulip_exit;
    k->vendor_id = PCI_VENDOR_ID_DEC;
    k->device_id = PCI_DEVICE_ID_DEC_21143;
-    k->subsystem_vendor_id = 0x103c;
+    k->subsystem_vendor_id = PCI_VENDOR_ID_HP;
    k->subsystem_id = 0x104f;
    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
    dc->vmsd = _pci_tulip;
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index 85469b9b53..3c0e72df0e 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -171,6 +171,8 @@
#define PCI_VENDOR_ID_DEC    0x1011
#define PCI_DEVICE_ID_DEC_21143  0x0019

+#define PCI_VENDOR_ID_HP 0x103c
+


Did not notice this in first round, sorry. These seems to be sorted
(there's a comment further up about that) so this should be between
AMD and TI a bit more down.


The list isn't sorted at all. I think the comment just wants to


It is still mostly sorted except where people did not get how. Try

grep PCI_VENDOR_ID_ pci_ids.h


say that you should mention the vendor before the devices.


I think it says that PCI_VENDOR_IDs should be sorted and then DEVICE_IDs within 
them should also be sorted but device IDs intervene VENDOR_IDs so the sorting 
of VENDOR_IDs may not be obvious at first sight.


Anyway, as the list currently is, there are multiple positions
where HP could be added...


Yes, some IDs already break this sorting but we could still avoid breaking it 
more. [...]


... that's why I added "HP" it after "DEC" :-)


But it should be sorted by ID number not name that's why it should be between 
AMD 0x1022 and TI 0x104c.


Oh, I see!
It's sorted by *numeric* PCI ID number.
Will fix in next round or before final pull request.

Helge



[PATCH] migration: Fix parse_ramblock() on overwritten retvals

2023-10-17 Thread Peter Xu
It's possible that some errors can be overwritten with success retval later
on, and then ignored.  Always capture all errors and report.

Reported by Coverity 1522861, but actually I spot one more in the same
function.

Fixes: CID 1522861
Signed-off-by: Peter Xu 
---
 migration/ram.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index c844151ee9..d8bdb53a8f 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3888,6 +3888,8 @@ static int parse_ramblock(QEMUFile *f, RAMBlock *block, 
ram_addr_t length)
 ret = qemu_ram_resize(block, length, _err);
 if (local_err) {
 error_report_err(local_err);
+assert(ret < 0);
+return ret;
 }
 }
 /* For postcopy we need to check hugepage sizes match */
@@ -3898,7 +3900,7 @@ static int parse_ramblock(QEMUFile *f, RAMBlock *block, 
ram_addr_t length)
 error_report("Mismatched RAM page size %s "
  "(local) %zd != %" PRId64, block->idstr,
  block->page_size, remote_page_size);
-ret = -EINVAL;
+return -EINVAL;
 }
 }
 if (migrate_ignore_shared()) {
@@ -3908,7 +3910,7 @@ static int parse_ramblock(QEMUFile *f, RAMBlock *block, 
ram_addr_t length)
 error_report("Mismatched GPAs for block %s "
  "%" PRId64 "!= %" PRId64, block->idstr,
  (uint64_t)addr, (uint64_t)block->mr->addr);
-ret = -EINVAL;
+return -EINVAL;
 }
 }
 ret = rdma_block_notification_handle(f, block->idstr);
-- 
2.41.0




[PATCH v4 3/5] tests/migration-test: Add a test for postcopy hangs during RECOVER

2023-10-17 Thread Peter Xu
From: Fabiano Rosas 

To do so, create two paired sockets, but make them not providing real data.
Feed those fake sockets to src/dst QEMUs for recovery to let them go into
RECOVER stage without going out.  Test that we can always kick it out and
recover again with the right ports.

This patch is based on Fabiano's version here:

https://lore.kernel.org/r/877cowmdu0@suse.de

Signed-off-by: Fabiano Rosas 
[peterx: write commit message, remove case 1, fix bugs, and more]
Signed-off-by: Peter Xu 
---
 tests/qtest/migration-test.c | 102 ---
 1 file changed, 96 insertions(+), 6 deletions(-)

diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index e1c110537b..e81d6de000 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -726,6 +726,7 @@ typedef struct {
 /* Postcopy specific fields */
 void *postcopy_data;
 bool postcopy_preempt;
+bool postcopy_recovery_test_fail;
 } MigrateCommon;
 
 static int test_migrate_start(QTestState **from, QTestState **to,
@@ -1379,6 +1380,78 @@ static void test_postcopy_preempt_tls_psk(void)
 }
 #endif
 
+static void wait_for_postcopy_status(QTestState *one, const char *status)
+{
+wait_for_migration_status(one, status,
+  (const char * []) { "failed", "active",
+  "completed", NULL });
+}
+
+static void postcopy_recover_fail(QTestState *from, QTestState *to)
+{
+int ret, pair1[2], pair2[2];
+char c;
+
+/* Create two unrelated socketpairs */
+ret = qemu_socketpair(PF_LOCAL, SOCK_STREAM, 0, pair1);
+g_assert_cmpint(ret, ==, 0);
+
+ret = qemu_socketpair(PF_LOCAL, SOCK_STREAM, 0, pair2);
+g_assert_cmpint(ret, ==, 0);
+
+/*
+ * Give the guests unpaired ends of the sockets, so they'll all blocked
+ * at reading.  This mimics a wrong channel established.
+ */
+qtest_qmp_fds_assert_success(from, [0], 1,
+ "{ 'execute': 'getfd',"
+ "  'arguments': { 'fdname': 'fd-mig' }}");
+qtest_qmp_fds_assert_success(to, [0], 1,
+ "{ 'execute': 'getfd',"
+ "  'arguments': { 'fdname': 'fd-mig' }}");
+
+/*
+ * Write the 1st byte as QEMU_VM_COMMAND (0x8) for the dest socket, to
+ * emulate the 1st byte of a real recovery, but stops from there to
+ * keep dest QEMU in RECOVER.  This is needed so that we can kick off
+ * the recover process on dest QEMU (by triggering the G_IO_IN event).
+ *
+ * NOTE: this trick is not needed on src QEMUs, because src doesn't
+ * rely on an pre-existing G_IO_IN event, so it will always trigger the
+ * upcoming recovery anyway even if it can read nothing.
+ */
+#define QEMU_VM_COMMAND  0x08
+c = QEMU_VM_COMMAND;
+ret = send(pair2[1], , 1, 0);
+g_assert_cmpint(ret, ==, 1);
+
+migrate_recover(to, "fd:fd-mig");
+migrate_qmp(from, "fd:fd-mig", "{'resume': true}");
+
+/*
+ * Make sure both QEMU instances will go into RECOVER stage, then test
+ * kicking them out using migrate-pause.
+ */
+wait_for_postcopy_status(from, "postcopy-recover");
+wait_for_postcopy_status(to, "postcopy-recover");
+
+/*
+ * This would be issued by the admin upon noticing the hang, we should
+ * make sure we're able to kick this out.
+ */
+migrate_pause(from);
+wait_for_postcopy_status(from, "postcopy-paused");
+
+/* Do the same test on dest */
+migrate_pause(to);
+wait_for_postcopy_status(to, "postcopy-paused");
+
+close(pair1[0]);
+close(pair1[1]);
+close(pair2[0]);
+close(pair2[1]);
+}
+
 static void test_postcopy_recovery_common(MigrateCommon *args)
 {
 QTestState *from, *to;
@@ -1414,9 +1487,17 @@ static void test_postcopy_recovery_common(MigrateCommon 
*args)
  * migrate-recover command can only succeed if destination machine
  * is in the paused state
  */
-wait_for_migration_status(to, "postcopy-paused",
-  (const char * []) { "failed", "active",
-  "completed", NULL });
+wait_for_postcopy_status(to, "postcopy-paused");
+wait_for_postcopy_status(from, "postcopy-paused");
+
+if (args->postcopy_recovery_test_fail) {
+/*
+ * Test when a wrong socket specified for recover, and then the
+ * ability to kick it out, and continue with a correct socket.
+ */
+postcopy_recover_fail(from, to);
+/* continue with a good recovery */
+}
 
 /*
  * Create a new socket to emulate a new channel that is different
@@ -1430,9 +1511,6 @@ static void test_postcopy_recovery_common(MigrateCommon 
*args)
  * Try to rebuild the migration channel using the resume flag and
  * the newly created channel
  */
-wait_for_migration_status(from, 

[PATCH v4 1/5] migration: Refactor error handling in source return path

2023-10-17 Thread Peter Xu
rp_state.error was a boolean used to show error happened in return path
thread.  That's not only duplicating error reporting (migrate_set_error),
but also not good enough in that we only do error_report() and set it to
true, we never can keep a history of the exact error and show it in
query-migrate.

To make this better, a few things done:

  - Use error_setg() rather than error_report() across the whole lifecycle
of return path thread, keeping the error in an Error*.

  - With above, no need to have mark_source_rp_bad(), remove it, alongside
with rp_state.error itself.

  - Use migrate_set_error() to apply that captured error to the global
migration object when error occured in this thread.

  - Do the same when detected qemufile error in source return path

We need to re-export qemu_file_get_error_obj() to do the last one.

Signed-off-by: Peter Xu 
---
 migration/migration.h  |   1 -
 migration/qemu-file.h  |   1 +
 migration/ram.h|   5 +-
 migration/migration.c  | 121 ++---
 migration/qemu-file.c  |   2 +-
 migration/ram.c|  41 +++---
 migration/trace-events |   4 +-
 7 files changed, 80 insertions(+), 95 deletions(-)

diff --git a/migration/migration.h b/migration/migration.h
index ae82004892..1d1ac13adb 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -308,7 +308,6 @@ struct MigrationState {
 /* Protected by qemu_file_lock */
 QEMUFile *from_dst_file;
 QemuThreadrp_thread;
-bool  error;
 /*
  * We can also check non-zero of rp_thread, but there's no "official"
  * way to do this, so this bool makes it slightly more elegant.
diff --git a/migration/qemu-file.h b/migration/qemu-file.h
index a29c37b0d0..25a1a8052f 100644
--- a/migration/qemu-file.h
+++ b/migration/qemu-file.h
@@ -87,6 +87,7 @@ int coroutine_mixed_fn qemu_peek_byte(QEMUFile *f, int 
offset);
 void qemu_file_skip(QEMUFile *f, int size);
 int qemu_file_get_error_obj_any(QEMUFile *f1, QEMUFile *f2, Error **errp);
 void qemu_file_set_error_obj(QEMUFile *f, int ret, Error *err);
+int qemu_file_get_error_obj(QEMUFile *f, Error **errp);
 void qemu_file_set_error(QEMUFile *f, int ret);
 int qemu_file_shutdown(QEMUFile *f);
 QEMUFile *qemu_file_get_return_path(QEMUFile *f);
diff --git a/migration/ram.h b/migration/ram.h
index 145c915ca7..14ed666d58 100644
--- a/migration/ram.h
+++ b/migration/ram.h
@@ -51,7 +51,8 @@ uint64_t ram_bytes_total(void);
 void mig_throttle_counter_reset(void);
 
 uint64_t ram_pagesize_summary(void);
-int ram_save_queue_pages(const char *rbname, ram_addr_t start, ram_addr_t len);
+int ram_save_queue_pages(const char *rbname, ram_addr_t start, ram_addr_t len,
+ Error **errp);
 void ram_postcopy_migrated_memory_release(MigrationState *ms);
 /* For outgoing discard bitmap */
 void ram_postcopy_send_discard_bitmap(MigrationState *ms);
@@ -71,7 +72,7 @@ void ramblock_recv_bitmap_set(RAMBlock *rb, void *host_addr);
 void ramblock_recv_bitmap_set_range(RAMBlock *rb, void *host_addr, size_t nr);
 int64_t ramblock_recv_bitmap_send(QEMUFile *file,
   const char *block_name);
-int ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *rb);
+int ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *rb, Error **errp);
 bool ramblock_page_is_discarded(RAMBlock *rb, ram_addr_t start);
 void postcopy_preempt_shutdown_file(MigrationState *s);
 void *postcopy_preempt_thread(void *opaque);
diff --git a/migration/migration.c b/migration/migration.c
index 6ba5e145ac..3123c4a873 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -99,7 +99,7 @@ static int migration_maybe_pause(MigrationState *s,
  int *current_active_state,
  int new_state);
 static void migrate_fd_cancel(MigrationState *s);
-static int close_return_path_on_source(MigrationState *s);
+static bool close_return_path_on_source(MigrationState *s);
 
 static bool migration_needs_multiple_sockets(void)
 {
@@ -1430,7 +1430,6 @@ int migrate_init(MigrationState *s, Error **errp)
 s->to_dst_file = NULL;
 s->state = MIGRATION_STATUS_NONE;
 s->rp_state.from_dst_file = NULL;
-s->rp_state.error = false;
 s->mbps = 0.0;
 s->pages_per_second = 0.0;
 s->downtime = 0;
@@ -1755,16 +1754,6 @@ void qmp_migrate_continue(MigrationStatus state, Error 
**errp)
 qemu_sem_post(>pause_sem);
 }
 
-/* migration thread support */
-/*
- * Something bad happened to the RP stream, mark an error
- * The caller shall print or trace something to indicate why
- */
-static void mark_source_rp_bad(MigrationState *s)
-{
-s->rp_state.error = true;
-}
-
 void migration_rp_wait(MigrationState *s)
 {
 qemu_sem_wait(>rp_state.rp_sem);
@@ -1795,8 +1784,9 @@ static struct rp_cmd_args {
  * We're allowed to send more than requested (e.g. to round to our page size)
  * and we don't need to send 

[PATCH v4 5/5] migration: Change ram_save_queue_pages() retval to bool

2023-10-17 Thread Peter Xu
After we have errp which contains the more detailed error message, make
ram_save_queue_pages() returns bool in its stack.

Signed-off-by: Peter Xu 
---
 migration/ram.h   |  4 ++--
 migration/migration.c | 16 
 migration/ram.c   | 18 +-
 3 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/migration/ram.h b/migration/ram.h
index af0290f8ab..e22a6b0d1c 100644
--- a/migration/ram.h
+++ b/migration/ram.h
@@ -51,8 +51,8 @@ uint64_t ram_bytes_total(void);
 void mig_throttle_counter_reset(void);
 
 uint64_t ram_pagesize_summary(void);
-int ram_save_queue_pages(const char *rbname, ram_addr_t start, ram_addr_t len,
- Error **errp);
+bool ram_save_queue_pages(const char *rbname, ram_addr_t start,
+  ram_addr_t len, Error **errp);
 void ram_postcopy_migrated_memory_release(MigrationState *ms);
 /* For outgoing discard bitmap */
 void ram_postcopy_send_discard_bitmap(MigrationState *ms);
diff --git a/migration/migration.c b/migration/migration.c
index dfb8b48dcb..50bf8422c7 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1820,8 +1820,10 @@ static struct rp_cmd_args {
  * Process a request for pages received on the return path,
  * We're allowed to send more than requested (e.g. to round to our page size)
  * and we don't need to send pages that have already been sent.
+ *
+ * Returns true if succeed, false otherwise.
  */
-static void
+static bool
 migrate_handle_rp_req_pages(MigrationState *ms, const char* rbname,
 ram_addr_t start, size_t len, Error **errp)
 {
@@ -1837,10 +1839,10 @@ migrate_handle_rp_req_pages(MigrationState *ms, const 
char* rbname,
 !QEMU_IS_ALIGNED(len, our_host_ps)) {
 error_setg(errp, "MIG_RP_MSG_REQ_PAGES: Misaligned page request, 
start:"
RAM_ADDR_FMT " len: %zd", start, len);
-return;
+return false;
 }
 
-ram_save_queue_pages(rbname, start, len, errp);
+return ram_save_queue_pages(rbname, start, len, errp);
 }
 
 static bool migrate_handle_rp_recv_bitmap(MigrationState *s, char *block_name,
@@ -1990,8 +1992,7 @@ static void *source_return_path_thread(void *opaque)
 case MIG_RP_MSG_REQ_PAGES:
 start = ldq_be_p(buf);
 len = ldl_be_p(buf + 8);
-migrate_handle_rp_req_pages(ms, NULL, start, len, );
-if (err) {
+if (!migrate_handle_rp_req_pages(ms, NULL, start, len, )) {
 goto out;
 }
 break;
@@ -2012,9 +2013,8 @@ static void *source_return_path_thread(void *opaque)
header_len, expected_len);
 goto out;
 }
-migrate_handle_rp_req_pages(ms, (char *)[13], start, len,
-);
-if (err) {
+if (!migrate_handle_rp_req_pages(ms, (char *)[13], start, len,
+ )) {
 goto out;
 }
 break;
diff --git a/migration/ram.c b/migration/ram.c
index ca77444e18..aca9ae5846 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1948,15 +1948,15 @@ static void migration_page_queue_free(RAMState *rs)
  *
  * A request from postcopy destination for example.
  *
- * Returns zero on success or negative on error
+ * Returns true on success or false on error (detailed error put in @errp)
  *
  * @rbname: Name of the RAMBLock of the request. NULL means the
  *  same that last one.
  * @start: starting address from the start of the RAMBlock
  * @len: length (in bytes) to send
  */
-int ram_save_queue_pages(const char *rbname, ram_addr_t start, ram_addr_t len,
- Error **errp)
+bool ram_save_queue_pages(const char *rbname, ram_addr_t start,
+  ram_addr_t len, Error **errp)
 {
 RAMBlock *ramblock;
 RAMState *rs = ram_state;
@@ -1974,7 +1974,7 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t 
start, ram_addr_t len,
  * it's the 1st request.
  */
 error_setg(errp, "MIG_RP_MSG_REQ_PAGES has no previous block");
-return -1;
+return false;
 }
 } else {
 ramblock = qemu_ram_block_by_name(rbname);
@@ -1982,7 +1982,7 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t 
start, ram_addr_t len,
 if (!ramblock) {
 /* We shouldn't be asked for a non-existent RAMBlock */
 error_setg(errp, "MIG_RP_MSG_REQ_PAGES has no block '%s'", rbname);
-return -1;
+return false;
 }
 rs->last_req_rb = ramblock;
 }
@@ -1992,7 +1992,7 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t 
start, ram_addr_t len,
"start=" RAM_ADDR_FMT " len="
RAM_ADDR_FMT " blocklen=" RAM_ADDR_FMT,
start, len, ramblock->used_length);
-return -1;
+

[PATCH 09/11] hw/net/cadence_gem: use FIELD to describe PHYMNTNC register fields

2023-10-17 Thread Luc Michel
Use the FIELD macro to describe the PHYMNTNC register fields.

Signed-off-by: Luc Michel 
---
 hw/net/cadence_gem.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 955a8da134..4c5fe10316 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -192,10 +192,18 @@ REG32(ISR, 0x24) /* Interrupt Status reg */
 REG32(IER, 0x28) /* Interrupt Enable reg */
 REG32(IDR, 0x2c) /* Interrupt Disable reg */
 REG32(IMR, 0x30) /* Interrupt Mask reg */
 
 REG32(PHYMNTNC, 0x34) /* Phy Maintenance reg */
+FIELD(PHYMNTNC, DATA, 0, 16)
+FIELD(PHYMNTNC, REG_ADDR, 18, 5)
+FIELD(PHYMNTNC, PHY_ADDR, 23, 5)
+FIELD(PHYMNTNC, OP, 28, 2)
+FIELD(PHYMNTNC, ST, 30, 2)
+#define MDIO_OP_READ0x3
+#define MDIO_OP_WRITE   0x2
+
 REG32(RXPAUSE, 0x38) /* RX Pause Time reg */
 REG32(TXPAUSE, 0x3c) /* TX Pause Time reg */
 REG32(TXPARTIALSF, 0x40) /* TX Partial Store and Forward */
 REG32(RXPARTIALSF, 0x44) /* RX Partial Store and Forward */
 REG32(JUMBO_MAX_LEN, 0x48) /* Max Jumbo Frame Size */
@@ -340,17 +348,10 @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
 
 /*/
 
 
 
-#define GEM_PHYMNTNC_OP_R  0x2000 /* read operation */
-#define GEM_PHYMNTNC_OP_W  0x1000 /* write operation */
-#define GEM_PHYMNTNC_ADDR  0x0F80 /* Address bits */
-#define GEM_PHYMNTNC_ADDR_SHFT 23
-#define GEM_PHYMNTNC_REG   0x007C /* register bits */
-#define GEM_PHYMNTNC_REG_SHIFT 18
-
 /* Marvell PHY definitions */
 #define BOARD_PHY_ADDRESS0 /* PHY address we will emulate a device at */
 
 #define PHY_REG_CONTROL  0
 #define PHY_REG_STATUS   1
@@ -1539,16 +1540,16 @@ static uint64_t gem_read(void *opaque, hwaddr offset, 
unsigned size)
 case R_ISR:
 DB_PRINT("lowering irqs on ISR read\n");
 /* The interrupts get updated at the end of the function. */
 break;
 case R_PHYMNTNC:
-if (retval & GEM_PHYMNTNC_OP_R) {
+if (FIELD_EX32(retval, PHYMNTNC, OP) == MDIO_OP_READ) {
 uint32_t phy_addr, reg_num;
 
-phy_addr = (retval & GEM_PHYMNTNC_ADDR) >> GEM_PHYMNTNC_ADDR_SHFT;
+phy_addr = FIELD_EX32(retval, PHYMNTNC, PHY_ADDR);
 if (phy_addr == s->phy_addr) {
-reg_num = (retval & GEM_PHYMNTNC_REG) >> 
GEM_PHYMNTNC_REG_SHIFT;
+reg_num = FIELD_EX32(retval, PHYMNTNC, REG_ADDR);
 retval &= 0x;
 retval |= gem_phy_read(s, reg_num);
 } else {
 retval |= 0x; /* No device at this address */
 }
@@ -1662,16 +1663,16 @@ static void gem_write(void *opaque, hwaddr offset, 
uint64_t val,
 case R_SPADDR3HI:
 case R_SPADDR4HI:
 s->sar_active[(offset - R_SPADDR1HI) / 2] = true;
 break;
 case R_PHYMNTNC:
-if (val & GEM_PHYMNTNC_OP_W) {
+if (FIELD_EX32(val, PHYMNTNC, OP) == MDIO_OP_WRITE) {
 uint32_t phy_addr, reg_num;
 
-phy_addr = (val & GEM_PHYMNTNC_ADDR) >> GEM_PHYMNTNC_ADDR_SHFT;
+phy_addr = FIELD_EX32(val, PHYMNTNC, PHY_ADDR);
 if (phy_addr == s->phy_addr) {
-reg_num = (val & GEM_PHYMNTNC_REG) >> GEM_PHYMNTNC_REG_SHIFT;
+reg_num = FIELD_EX32(val, PHYMNTNC, REG_ADDR);
 gem_phy_write(s, reg_num, val);
 }
 }
 break;
 }
-- 
2.39.2




[PATCH 02/11] hw/net/cadence_gem: use FIELD for screening registers

2023-10-17 Thread Luc Michel
Describe screening registers fields using the FIELD macros.

Signed-off-by: Luc Michel 
---
 hw/net/cadence_gem.c | 92 ++--
 1 file changed, 47 insertions(+), 45 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 0e5744ecd7..f01c81de97 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -168,39 +168,42 @@ REG32(INT_Q7_ENABLE, 0x618)
 
 REG32(INT_Q1_DISABLE, 0x620)
 REG32(INT_Q7_DISABLE, 0x638)
 
 REG32(SCREENING_TYPE1_REG0, 0x500)
-
-#define GEM_ST1R_UDP_PORT_MATCH_ENABLE  (1 << 29)
-#define GEM_ST1R_DSTC_ENABLE(1 << 28)
-#define GEM_ST1R_UDP_PORT_MATCH_SHIFT   (12)
-#define GEM_ST1R_UDP_PORT_MATCH_WIDTH   (27 - GEM_ST1R_UDP_PORT_MATCH_SHIFT + 
1)
-#define GEM_ST1R_DSTC_MATCH_SHIFT   (4)
-#define GEM_ST1R_DSTC_MATCH_WIDTH   (11 - GEM_ST1R_DSTC_MATCH_SHIFT + 1)
-#define GEM_ST1R_QUEUE_SHIFT(0)
-#define GEM_ST1R_QUEUE_WIDTH(3 - GEM_ST1R_QUEUE_SHIFT + 1)
+FIELD(SCREENING_TYPE1_REG0, QUEUE_NUM, 0, 4)
+FIELD(SCREENING_TYPE1_REG0, DSTC_MATCH, 4, 8)
+FIELD(SCREENING_TYPE1_REG0, UDP_PORT_MATCH, 12, 16)
+FIELD(SCREENING_TYPE1_REG0, DSTC_ENABLE, 28, 1)
+FIELD(SCREENING_TYPE1_REG0, UDP_PORT_MATCH_EN, 29, 1)
+FIELD(SCREENING_TYPE1_REG0, DROP_ON_MATCH, 30, 1)
 
 REG32(SCREENING_TYPE2_REG0, 0x540)
-
-#define GEM_ST2R_COMPARE_A_ENABLE   (1 << 18)
-#define GEM_ST2R_COMPARE_A_SHIFT(13)
-#define GEM_ST2R_COMPARE_WIDTH  (17 - GEM_ST2R_COMPARE_A_SHIFT + 1)
-#define GEM_ST2R_ETHERTYPE_ENABLE   (1 << 12)
-#define GEM_ST2R_ETHERTYPE_INDEX_SHIFT  (9)
-#define GEM_ST2R_ETHERTYPE_INDEX_WIDTH  (11 - GEM_ST2R_ETHERTYPE_INDEX_SHIFT \
-+ 1)
-#define GEM_ST2R_QUEUE_SHIFT(0)
-#define GEM_ST2R_QUEUE_WIDTH(3 - GEM_ST2R_QUEUE_SHIFT + 1)
+FIELD(SCREENING_TYPE2_REG0, QUEUE_NUM, 0, 4)
+FIELD(SCREENING_TYPE2_REG0, VLAN_PRIORITY, 4, 3)
+FIELD(SCREENING_TYPE2_REG0, VLAN_ENABLE, 8, 1)
+FIELD(SCREENING_TYPE2_REG0, ETHERTYPE_REG_INDEX, 9, 3)
+FIELD(SCREENING_TYPE2_REG0, ETHERTYPE_ENABLE, 12, 1)
+FIELD(SCREENING_TYPE2_REG0, COMPARE_A, 13, 5)
+FIELD(SCREENING_TYPE2_REG0, COMPARE_A_ENABLE, 18, 1)
+FIELD(SCREENING_TYPE2_REG0, COMPARE_B, 19, 5)
+FIELD(SCREENING_TYPE2_REG0, COMPARE_B_ENABLE, 24, 1)
+FIELD(SCREENING_TYPE2_REG0, COMPARE_C, 25, 5)
+FIELD(SCREENING_TYPE2_REG0, COMPARE_C_ENABLE, 30, 1)
+FIELD(SCREENING_TYPE2_REG0, DROP_ON_MATCH, 31, 1)
 
 REG32(SCREENING_TYPE2_ETHERTYPE_REG0, 0x6e0)
+
 REG32(TYPE2_COMPARE_0_WORD_0, 0x700)
+FIELD(TYPE2_COMPARE_0_WORD_0, MASK_VALUE, 0, 16)
+FIELD(TYPE2_COMPARE_0_WORD_0, COMPARE_VALUE, 16, 16)
 
-#define GEM_T2CW1_COMPARE_OFFSET_SHIFT  (7)
-#define GEM_T2CW1_COMPARE_OFFSET_WIDTH  (8 - GEM_T2CW1_COMPARE_OFFSET_SHIFT + 
1)
-#define GEM_T2CW1_OFFSET_VALUE_SHIFT(0)
-#define GEM_T2CW1_OFFSET_VALUE_WIDTH(6 - GEM_T2CW1_OFFSET_VALUE_SHIFT + 1)
+REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
+FIELD(TYPE2_COMPARE_0_WORD_1, OFFSET_VALUE, 0, 7)
+FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_OFFSET, 7, 2)
+FIELD(TYPE2_COMPARE_0_WORD_1, DISABLE_MASK, 9, 1)
+FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_VLAN_ID, 10, 1)
 
 /*/
 #define GEM_NWCTRL_TXSTART 0x0200 /* Transmit Enable */
 #define GEM_NWCTRL_TXENA   0x0008 /* Transmit Enable */
 #define GEM_NWCTRL_RXENA   0x0004 /* Receive Enable */
@@ -753,45 +756,43 @@ static int get_queue_from_screen(CadenceGEMState *s, 
uint8_t *rxbuf_ptr,
 reg = s->regs[R_SCREENING_TYPE1_REG0 + i];
 matched = false;
 mismatched = false;
 
 /* Screening is based on UDP Port */
-if (reg & GEM_ST1R_UDP_PORT_MATCH_ENABLE) {
+if (FIELD_EX32(reg, SCREENING_TYPE1_REG0, UDP_PORT_MATCH_EN)) {
 uint16_t udp_port = rxbuf_ptr[14 + 22] << 8 | rxbuf_ptr[14 + 23];
-if (udp_port == extract32(reg, GEM_ST1R_UDP_PORT_MATCH_SHIFT,
-   GEM_ST1R_UDP_PORT_MATCH_WIDTH)) {
+if (udp_port == FIELD_EX32(reg, SCREENING_TYPE1_REG0, 
UDP_PORT_MATCH)) {
 matched = true;
 } else {
 mismatched = true;
 }
 }
 
 /* Screening is based on DS/TC */
-if (reg & GEM_ST1R_DSTC_ENABLE) {
+if (FIELD_EX32(reg, SCREENING_TYPE1_REG0, DSTC_ENABLE)) {
 uint8_t dscp = rxbuf_ptr[14 + 1];
-if (dscp == extract32(reg, GEM_ST1R_DSTC_MATCH_SHIFT,
-   GEM_ST1R_DSTC_MATCH_WIDTH)) {
+if (dscp == FIELD_EX32(reg, SCREENING_TYPE1_REG0, DSTC_MATCH)) {
 matched = true;
 } else {
 mismatched = true;
 }
 }
 
 if (matched && !mismatched) {
-return extract32(reg, GEM_ST1R_QUEUE_SHIFT, GEM_ST1R_QUEUE_WIDTH);
+return FIELD_EX32(reg, 

[PATCH 03/11] hw/net/cadence_gem: use FIELD to describe NWCTRL register fields

2023-10-17 Thread Luc Michel
Use the FIELD macro to describe the NWCTRL register fields.

Signed-off-by: Luc Michel 
---
 hw/net/cadence_gem.c | 53 +---
 1 file changed, 40 insertions(+), 13 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index f01c81de97..2864f0940e 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -44,10 +44,42 @@
 qemu_log(__VA_ARGS__); \
 } \
 } while (0)
 
 REG32(NWCTRL, 0x0) /* Network Control reg */
+FIELD(NWCTRL, LOOPBACK , 0, 1)
+FIELD(NWCTRL, LOOPBACK_LOCAL , 1, 1)
+FIELD(NWCTRL, ENABLE_RECEIVE, 2, 1)
+FIELD(NWCTRL, ENABLE_TRANSMIT, 3, 1)
+FIELD(NWCTRL, MAN_PORT_EN , 4, 1)
+FIELD(NWCTRL, CLEAR_ALL_STATS_REGS , 5, 1)
+FIELD(NWCTRL, INC_ALL_STATS_REGS, 6, 1)
+FIELD(NWCTRL, STATS_WRITE_EN, 7, 1)
+FIELD(NWCTRL, BACK_PRESSURE, 8, 1)
+FIELD(NWCTRL, TRANSMIT_START , 9, 1)
+FIELD(NWCTRL, TRANSMIT_HALT, 10, 1)
+FIELD(NWCTRL, TX_PAUSE_FRAME_RE, 11, 1)
+FIELD(NWCTRL, TX_PAUSE_FRAME_ZE, 12, 1)
+FIELD(NWCTRL, STATS_TAKE_SNAP, 13, 1)
+FIELD(NWCTRL, STATS_READ_SNAP, 14, 1)
+FIELD(NWCTRL, STORE_RX_TS, 15, 1)
+FIELD(NWCTRL, PFC_ENABLE, 16, 1)
+FIELD(NWCTRL, PFC_PRIO_BASED, 17, 1)
+FIELD(NWCTRL, FLUSH_RX_PKT_PCLK , 18, 1)
+FIELD(NWCTRL, TX_LPI_EN, 19, 1)
+FIELD(NWCTRL, PTP_UNICAST_ENA, 20, 1)
+FIELD(NWCTRL, ALT_SGMII_MODE, 21, 1)
+FIELD(NWCTRL, STORE_UDP_OFFSET, 22, 1)
+FIELD(NWCTRL, EXT_TSU_PORT_EN, 23, 1)
+FIELD(NWCTRL, ONE_STEP_SYNC_MO, 24, 1)
+FIELD(NWCTRL, PFC_CTRL , 25, 1)
+FIELD(NWCTRL, EXT_RXQ_SEL_EN , 26, 1)
+FIELD(NWCTRL, OSS_CORRECTION_FIELD, 27, 1)
+FIELD(NWCTRL, SEL_MII_ON_RGMII, 28, 1)
+FIELD(NWCTRL, TWO_PT_FIVE_GIG, 29, 1)
+FIELD(NWCTRL, IFG_EATS_QAV_CREDIT, 30, 1)
+
 REG32(NWCFG, 0x4) /* Network Config reg */
 REG32(NWSTATUS, 0x8) /* Network Status reg */
 REG32(USERIO, 0xc) /* User IO reg */
 REG32(DMACFG, 0x10) /* DMA Control reg */
 REG32(TXSTATUS, 0x14) /* TX Status reg */
@@ -202,15 +234,10 @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
 FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_OFFSET, 7, 2)
 FIELD(TYPE2_COMPARE_0_WORD_1, DISABLE_MASK, 9, 1)
 FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_VLAN_ID, 10, 1)
 
 /*/
-#define GEM_NWCTRL_TXSTART 0x0200 /* Transmit Enable */
-#define GEM_NWCTRL_TXENA   0x0008 /* Transmit Enable */
-#define GEM_NWCTRL_RXENA   0x0004 /* Receive Enable */
-#define GEM_NWCTRL_LOCALLOOP   0x0002 /* Local Loopback */
-
 #define GEM_NWCFG_STRIP_FCS0x0002 /* Strip FCS field */
 #define GEM_NWCFG_LERR_DISC0x0001 /* Discard RX frames with len err */
 #define GEM_NWCFG_BUFF_OFST_M  0xC000 /* Receive buffer offset mask */
 #define GEM_NWCFG_BUFF_OFST_S  14 /* Receive buffer offset shift */
 #define GEM_NWCFG_RCV_1538 0x0100 /* Receive 1538 bytes frame */
@@ -558,11 +585,11 @@ static bool gem_can_receive(NetClientState *nc)
 int i;
 
 s = qemu_get_nic_opaque(nc);
 
 /* Do nothing if receive is not enabled. */
-if (!(s->regs[R_NWCTRL] & GEM_NWCTRL_RXENA)) {
+if (!FIELD_EX32(s->regs[R_NWCTRL], NWCTRL, ENABLE_RECEIVE)) {
 if (s->can_rx_state != 1) {
 s->can_rx_state = 1;
 DB_PRINT("can't receive - no enable\n");
 }
 return false;
@@ -1171,11 +1198,11 @@ static void gem_transmit(CadenceGEMState *s)
 uint8_t *p;
 unsignedtotal_bytes;
 int q = 0;
 
 /* Do nothing if transmit is not enabled. */
-if (!(s->regs[R_NWCTRL] & GEM_NWCTRL_TXENA)) {
+if (!FIELD_EX32(s->regs[R_NWCTRL], NWCTRL, ENABLE_TRANSMIT)) {
 return;
 }
 
 DB_PRINT("\n");
 
@@ -1196,11 +1223,11 @@ static void gem_transmit(CadenceGEMState *s)
sizeof(uint32_t) * gem_get_desc_len(s, false));
 /* Handle all descriptors owned by hardware */
 while (tx_desc_get_used(desc) == 0) {
 
 /* Do nothing if transmit is not enabled. */
-if (!(s->regs[R_NWCTRL] & GEM_NWCTRL_TXENA)) {
+if (!FIELD_EX32(s->regs[R_NWCTRL], NWCTRL, ENABLE_TRANSMIT)) {
 return;
 }
 print_gem_tx_desc(desc, q);
 
 /* The real hardware would eat this (and possibly crash).
@@ -1269,12 +1296,12 @@ static void gem_transmit(CadenceGEMState *s)
 
 /* Update MAC statistics */
 gem_transmit_updatestats(s, s->tx_packet, total_bytes);
 
 /* Send the packet somewhere */
-if (s->phy_loop || (s->regs[R_NWCTRL] &
-GEM_NWCTRL_LOCALLOOP)) {
+if (s->phy_loop || FIELD_EX32(s->regs[R_NWCTRL], NWCTRL,
+  LOOPBACK_LOCAL)) {
 qemu_receive_packet(qemu_get_queue(s->nic), s->tx_packet,
 total_bytes);
 } else {

[PATCH 08/11] hw/net/cadence_gem: use FIELD to describe DESCONF6 register fields

2023-10-17 Thread Luc Michel
Use the FIELD macro to describe the DESCONF6 register fields.

Signed-off-by: Luc Michel 
---
 hw/net/cadence_gem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 6d084a3b31..955a8da134 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -281,11 +281,11 @@ REG32(DESCONF, 0x280)
 REG32(DESCONF2, 0x284)
 REG32(DESCONF3, 0x288)
 REG32(DESCONF4, 0x28c)
 REG32(DESCONF5, 0x290)
 REG32(DESCONF6, 0x294)
-#define GEM_DESCONF6_64B_MASK (1U << 23)
+FIELD(DESCONF6, DMA_ADDR_64B, 23, 1)
 REG32(DESCONF7, 0x298)
 
 REG32(INT_Q1_STATUS, 0x400)
 REG32(INT_Q1_MASK, 0x640)
 
@@ -1461,11 +1461,11 @@ static void gem_reset(DeviceState *d)
 s->regs[R_RXPARTIALSF] = 0x03ff;
 s->regs[R_MODID] = s->revision;
 s->regs[R_DESCONF] = 0x02D00111;
 s->regs[R_DESCONF2] = 0x2ab1 | s->jumbo_max_len;
 s->regs[R_DESCONF5] = 0x002f2045;
-s->regs[R_DESCONF6] = GEM_DESCONF6_64B_MASK;
+s->regs[R_DESCONF6] = R_DESCONF6_DMA_ADDR_64B_MASK;
 s->regs[R_INT_Q1_MASK] = 0x0CE6;
 s->regs[R_JUMBO_MAX_LEN] = s->jumbo_max_len;
 
 if (s->num_priority_queues > 1) {
 queues_mask = MAKE_64BIT_MASK(1, s->num_priority_queues - 1);
-- 
2.39.2




[PATCH 04/11] hw/net/cadence_gem: use FIELD to describe NWCFG register fields

2023-10-17 Thread Luc Michel
Use de FIELD macro to describe the NWCFG register fields.

Signed-off-by: Luc Michel 
---
 hw/net/cadence_gem.c | 60 
 1 file changed, 39 insertions(+), 21 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 2864f0940e..09f570b6fb 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -77,10 +77,39 @@ REG32(NWCTRL, 0x0) /* Network Control reg */
 FIELD(NWCTRL, SEL_MII_ON_RGMII, 28, 1)
 FIELD(NWCTRL, TWO_PT_FIVE_GIG, 29, 1)
 FIELD(NWCTRL, IFG_EATS_QAV_CREDIT, 30, 1)
 
 REG32(NWCFG, 0x4) /* Network Config reg */
+FIELD(NWCFG, SPEED, 0, 1)
+FIELD(NWCFG, FULL_DUPLEX, 1, 1)
+FIELD(NWCFG, DISCARD_NON_VLAN_FRAMES, 2, 1)
+FIELD(NWCFG, JUMBO_FRAMES, 3, 1)
+FIELD(NWCFG, PROMISC, 4, 1)
+FIELD(NWCFG, NO_BROADCAST, 5, 1)
+FIELD(NWCFG, MULTICAST_HASH_EN, 6, 1)
+FIELD(NWCFG, UNICAST_HASH_EN, 7, 1)
+FIELD(NWCFG, RECV_1536_BYTE_FRAMES, 8, 1)
+FIELD(NWCFG, EXTERNAL_ADDR_MATCH_EN, 9, 1)
+FIELD(NWCFG, GIGABIT_MODE_ENABLE, 10, 1)
+FIELD(NWCFG, PCS_SELECT, 11, 1)
+FIELD(NWCFG, RETRY_TEST, 12, 1)
+FIELD(NWCFG, PAUSE_ENABLE, 13, 1)
+FIELD(NWCFG, RECV_BUF_OFFSET, 14, 2)
+FIELD(NWCFG, LEN_ERR_DISCARD, 16, 1)
+FIELD(NWCFG, FCS_REMOVE, 17, 1)
+FIELD(NWCFG, MDC_CLOCK_DIV, 18, 3)
+FIELD(NWCFG, DATA_BUS_WIDTH, 21, 2)
+FIELD(NWCFG, DISABLE_COPY_PAUSE_FRAMES, 23, 1)
+FIELD(NWCFG, RECV_CSUM_OFFLOAD_EN, 24, 1)
+FIELD(NWCFG, EN_HALF_DUPLEX_RX, 25, 1)
+FIELD(NWCFG, IGNORE_RX_FCS, 26, 1)
+FIELD(NWCFG, SGMII_MODE_ENABLE, 27, 1)
+FIELD(NWCFG, IPG_STRETCH_ENABLE, 28, 1)
+FIELD(NWCFG, NSP_ACCEPT, 29, 1)
+FIELD(NWCFG, IGNORE_IPG_RX_ER, 30, 1)
+FIELD(NWCFG, UNI_DIRECTION_ENABLE, 31, 1)
+
 REG32(NWSTATUS, 0x8) /* Network Status reg */
 REG32(USERIO, 0xc) /* User IO reg */
 REG32(DMACFG, 0x10) /* DMA Control reg */
 REG32(TXSTATUS, 0x14) /* TX Status reg */
 REG32(RXQBASE, 0x18) /* RX Q Base address reg */
@@ -234,21 +263,10 @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
 FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_OFFSET, 7, 2)
 FIELD(TYPE2_COMPARE_0_WORD_1, DISABLE_MASK, 9, 1)
 FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_VLAN_ID, 10, 1)
 
 /*/
-#define GEM_NWCFG_STRIP_FCS0x0002 /* Strip FCS field */
-#define GEM_NWCFG_LERR_DISC0x0001 /* Discard RX frames with len err */
-#define GEM_NWCFG_BUFF_OFST_M  0xC000 /* Receive buffer offset mask */
-#define GEM_NWCFG_BUFF_OFST_S  14 /* Receive buffer offset shift */
-#define GEM_NWCFG_RCV_1538 0x0100 /* Receive 1538 bytes frame */
-#define GEM_NWCFG_UCAST_HASH   0x0080 /* accept unicast if hash match */
-#define GEM_NWCFG_MCAST_HASH   0x0040 /* accept multicast if hash match */
-#define GEM_NWCFG_BCAST_REJ0x0020 /* Reject broadcast packets */
-#define GEM_NWCFG_PROMISC  0x0010 /* Accept all packets */
-#define GEM_NWCFG_JUMBO_FRAME  0x0008 /* Jumbo Frames enable */
-
 #define GEM_DMACFG_ADDR_64B(1U << 30)
 #define GEM_DMACFG_TX_BD_EXT   (1U << 29)
 #define GEM_DMACFG_RX_BD_EXT   (1U << 28)
 #define GEM_DMACFG_RBUFSZ_M0x00FF /* DMA RX Buffer Size mask */
 #define GEM_DMACFG_RBUFSZ_S16 /* DMA RX Buffer Size shift */
@@ -480,21 +498,22 @@ static inline void rx_desc_set_sar(uint32_t *desc, int 
sar_idx)
 static const uint8_t broadcast_addr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 
 static uint32_t gem_get_max_buf_len(CadenceGEMState *s, bool tx)
 {
 uint32_t size;
-if (s->regs[R_NWCFG] & GEM_NWCFG_JUMBO_FRAME) {
+if (FIELD_EX32(s->regs[R_NWCFG], NWCFG, JUMBO_FRAMES)) {
 size = s->regs[R_JUMBO_MAX_LEN];
 if (size > s->jumbo_max_len) {
 size = s->jumbo_max_len;
 qemu_log_mask(LOG_GUEST_ERROR, "GEM_JUMBO_MAX_LEN reg cannot be"
 " greater than 0x%" PRIx32 "\n", s->jumbo_max_len);
 }
 } else if (tx) {
 size = 1518;
 } else {
-size = s->regs[R_NWCFG] & GEM_NWCFG_RCV_1538 ? 1538 : 1518;
+size = FIELD_EX32(s->regs[R_NWCFG],
+  NWCFG, RECV_1536_BYTE_FRAMES) ? 1538 : 1518;
 }
 return size;
 }
 
 static void gem_set_isr(CadenceGEMState *s, int q, uint32_t flag)
@@ -730,26 +749,26 @@ static int gem_mac_address_filter(CadenceGEMState *s, 
const uint8_t *packet)
 {
 uint8_t *gem_spaddr;
 int i, is_mc;
 
 /* Promiscuous mode? */
-if (s->regs[R_NWCFG] & GEM_NWCFG_PROMISC) {
+if (FIELD_EX32(s->regs[R_NWCFG], NWCFG, PROMISC)) {
 return GEM_RX_PROMISCUOUS_ACCEPT;
 }
 
 if (!memcmp(packet, broadcast_addr, 6)) {
 /* Reject broadcast packets? */
-if (s->regs[R_NWCFG] & GEM_NWCFG_BCAST_REJ) {
+if (FIELD_EX32(s->regs[R_NWCFG], NWCFG, NO_BROADCAST)) {
 return GEM_RX_REJECT;
 }
 return GEM_RX_BROADCAST_ACCEPT;
 }
 
 /* Accept packets -w- hash match? */
 is_mc = 

[PATCH 00/11] Various updates for the Cadence GEM model

2023-10-17 Thread Luc Michel
Hi,

This series brings small changes to the Cadence GEM Ethernet model.
There is (almost) no behaviour change.

Patches 1 to 9 replace handcrafted defines with the use of REG32 and
FIELDS macros for register and fields declarations.

Patch 10 fixes PHY accesses so that they are done only on a write to the
PHYMNTNC register (as the real hardware does).

Patch 11 fixes a potential bug on hosts where unsigned would not be 32
bits.

Thanks,

-- 
Luc

Luc Michel (11):
  hw/net/cadence_gem: use REG32 macro for register definitions
  hw/net/cadence_gem: use FIELD for screening registers
  hw/net/cadence_gem: use FIELD to describe NWCTRL register fields
  hw/net/cadence_gem: use FIELD to describe NWCFG register fields
  hw/net/cadence_gem: use FIELD to describe DMACFG register fields
  hw/net/cadence_gem: use FIELD to describe [TX|RX]STATUS register
fields
  hw/net/cadence_gem: use FIELD to describe IRQ register fields
  hw/net/cadence_gem: use FIELD to describe DESCONF6 register fields
  hw/net/cadence_gem: use FIELD to describe PHYMNTNC register fields
  hw/net/cadence_gem: perform PHY access on write only
  hw/net/cadence_gem: enforce 32 bits variable size for CRC

 hw/net/cadence_gem.c | 910 ---
 1 file changed, 510 insertions(+), 400 deletions(-)

-- 
2.39.2




[PATCH v4 2/5] migration: Allow network to fail even during recovery

2023-10-17 Thread Peter Xu
Normally the postcopy recover phase should only exist for a super short
period, that's the duration when QEMU is trying to recover from an
interrupted postcopy migration, during which handshake will be carried out
for continuing the procedure with state changes from PAUSED -> RECOVER ->
POSTCOPY_ACTIVE again.

Here RECOVER phase should be super small, that happens right after the
admin specified a new but working network link for QEMU to reconnect to
dest QEMU.

However there can still be case where the channel is broken in this small
RECOVER window.

If it happens, with current code there's no way the src QEMU can got kicked
out of RECOVER stage. No way either to retry the recover in another channel
when established.

This patch allows the RECOVER phase to fail itself too - we're mostly
ready, just some small things missing, e.g. properly kick the main
migration thread out when sleeping on rp_sem when we found that we're at
RECOVER stage.  When this happens, it fails the RECOVER itself, and
rollback to PAUSED stage.  Then the user can retry another round of
recovery.

To make it even stronger, teach QMP command migrate-pause to explicitly
kick src/dst QEMU out when needed, so even if for some reason the migration
thread didn't got kicked out already by a failing rethrn-path thread, the
admin can also kick it out.

This will be an super, super corner case, but still try to cover that.

One can try to test this with two proxy channels for migration:

  (a) socat unix-listen:/tmp/src.sock,reuseaddr,fork tcp:localhost:1
  (b) socat tcp-listen:1,reuseaddr,fork unix:/tmp/dst.sock

So the migration channel will be:

  (a)  (b)
  src -> /tmp/src.sock -> tcp:1 -> /tmp/dst.sock -> dst

Then to make QEMU hang at RECOVER stage, one can do below:

  (1) stop the postcopy using QMP command postcopy-pause
  (2) kill the 2nd proxy (b)
  (3) try to recover the postcopy using /tmp/src.sock on src
  (4) src QEMU will go into RECOVER stage but won't be able to continue
  from there, because the channel is actually broken at (b)

Before this patch, step (4) will make src QEMU stuck in RECOVER stage,
without a way to kick the QEMU out or continue the postcopy again.  After
this patch, (4) will quickly fail qemu and bounce back to PAUSED stage.

Admin can also kick QEMU from (4) into PAUSED when needed using
migrate-pause when needed.

After bouncing back to PAUSED stage, one can recover again.

Reported-by: Xiaohui Li 
Reviewed-by: Fabiano Rosas 
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2111332
Signed-off-by: Peter Xu 
---
 migration/migration.h |  8 --
 migration/migration.c | 63 +++
 migration/ram.c   |  4 ++-
 3 files changed, 67 insertions(+), 8 deletions(-)

diff --git a/migration/migration.h b/migration/migration.h
index 1d1ac13adb..0b695bbfb1 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -494,6 +494,7 @@ int migrate_init(MigrationState *s, Error **errp);
 bool migration_is_blocked(Error **errp);
 /* True if outgoing migration has entered postcopy phase */
 bool migration_in_postcopy(void);
+bool migration_postcopy_is_alive(int state);
 MigrationState *migrate_get_current(void);
 
 uint64_t ram_get_total_transferred_pages(void);
@@ -534,8 +535,11 @@ void migration_populate_vfio_info(MigrationInfo *info);
 void migration_reset_vfio_bytes_transferred(void);
 void postcopy_temp_page_reset(PostcopyTmpPage *tmp_page);
 
-/* Migration thread waiting for return path thread. */
-void migration_rp_wait(MigrationState *s);
+/*
+ * Migration thread waiting for return path thread.  Return non-zero if an
+ * error is detected.
+ */
+int migration_rp_wait(MigrationState *s);
 /*
  * Kick the migration thread waiting for return path messages.  NOTE: the
  * name can be slightly confusing (when read as "kick the rp thread"), just
diff --git a/migration/migration.c b/migration/migration.c
index 3123c4a873..0661dad953 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1348,6 +1348,17 @@ bool migration_in_postcopy(void)
 }
 }
 
+bool migration_postcopy_is_alive(int state)
+{
+switch (state) {
+case MIGRATION_STATUS_POSTCOPY_ACTIVE:
+case MIGRATION_STATUS_POSTCOPY_RECOVER:
+return true;
+default:
+return false;
+}
+}
+
 bool migration_in_postcopy_after_devices(MigrationState *s)
 {
 return migration_in_postcopy() && s->postcopy_after_devices;
@@ -1557,8 +1568,15 @@ void qmp_migrate_pause(Error **errp)
 MigrationIncomingState *mis = migration_incoming_get_current();
 int ret = 0;
 
-if (ms->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) {
+if (migration_postcopy_is_alive(ms->state)) {
 /* Source side, during postcopy */
+Error *error = NULL;
+
+/* Tell the core migration that we're pausing */
+error_setg(, "Postcopy migration is paused by the user");
+migrate_set_error(ms, error);
+error_free(error);

[PATCH v4 0/5] migration: Better error handling in rp thread, allow failures in recover

2023-10-17 Thread Peter Xu
v4:
- Some patches merged, reposting the rest patches
- Fixed a bug in the new test case reported by Fabiano
- Try to keep close_return_path_on_source() return a value (even though it
  still fetches from migrate_has_error)
- Two more patches added to cleanup retval of rp thread functions

v1: https://lore.kernel.org/r/20230829214235.69309-1-pet...@redhat.com
v2: https://lore.kernel.org/r/2023091145.731099-1-pet...@redhat.com
v3: https://lore.kernel.org/r/20231004220240.167175-1-pet...@redhat.com

This series allow better error handling in the postcopy return path thread,
so that we'll start to store the errors in MigrationState and can be seen
from query-migrate later, comparing to before where we do error_report()
and never remember the error.

Meanwhile, it allows double-failures to happen during postcopy recovery,
IOW, one can fail again right during RECOVER phase on both sides, even if
RECOVER phase should be an extremely small window.

Please have a look, thanks.

Fabiano Rosas (1):
  tests/migration-test: Add a test for postcopy hangs during RECOVER

Peter Xu (4):
  migration: Refactor error handling in source return path
  migration: Allow network to fail even during recovery
  migration: Change ram_dirty_bitmap_reload() retval to bool
  migration: Change ram_save_queue_pages() retval to bool

 migration/migration.h|   9 +-
 migration/qemu-file.h|   1 +
 migration/ram.h  |   5 +-
 migration/migration.c| 190 +--
 migration/qemu-file.c|   2 +-
 migration/ram.c  |  75 +++---
 tests/qtest/migration-test.c | 102 +--
 migration/trace-events   |   4 +-
 8 files changed, 261 insertions(+), 127 deletions(-)

-- 
2.41.0




[PATCH 11/11] hw/net/cadence_gem: enforce 32 bits variable size for CRC

2023-10-17 Thread Luc Michel
The CRC was stored in an unsigned variable in gem_receive. Change it for
a uint32_t to ensure we have the correct variable size here.

Signed-off-by: Luc Michel 
---
 hw/net/cadence_gem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 21146f4242..d52530bae4 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -1103,11 +1103,11 @@ static ssize_t gem_receive(NetClientState *nc, const 
uint8_t *buf, size_t size)
 
 /* Strip of FCS field ? (usually yes) */
 if (FIELD_EX32(s->regs[R_NWCFG], NWCFG, FCS_REMOVE)) {
 rxbuf_ptr = (void *)buf;
 } else {
-unsigned crc_val;
+uint32_t crc_val;
 
 if (size > MAX_FRAME_SIZE - sizeof(crc_val)) {
 size = MAX_FRAME_SIZE - sizeof(crc_val);
 }
 bytes_to_copy = size;
-- 
2.39.2




[PATCH 05/11] hw/net/cadence_gem: use FIELD to describe DMACFG register fields

2023-10-17 Thread Luc Michel
Use de FIELD macro to describe the DMACFG register fields.

Signed-off-by: Luc Michel 
---
 hw/net/cadence_gem.c | 48 
 1 file changed, 31 insertions(+), 17 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 09f570b6fb..5c386adff2 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -108,11 +108,31 @@ REG32(NWCFG, 0x4) /* Network Config reg */
 FIELD(NWCFG, IGNORE_IPG_RX_ER, 30, 1)
 FIELD(NWCFG, UNI_DIRECTION_ENABLE, 31, 1)
 
 REG32(NWSTATUS, 0x8) /* Network Status reg */
 REG32(USERIO, 0xc) /* User IO reg */
+
 REG32(DMACFG, 0x10) /* DMA Control reg */
+FIELD(DMACFG, SEND_BCAST_TO_ALL_QS, 31, 1)
+FIELD(DMACFG, DMA_ADDR_BUS_WIDTH, 30, 1)
+FIELD(DMACFG, TX_BD_EXT_MODE_EN , 29, 1)
+FIELD(DMACFG, RX_BD_EXT_MODE_EN , 28, 1)
+FIELD(DMACFG, FORCE_MAX_AMBA_BURST_TX, 26, 1)
+FIELD(DMACFG, FORCE_MAX_AMBA_BURST_RX, 25, 1)
+FIELD(DMACFG, FORCE_DISCARD_ON_ERR, 24, 1)
+FIELD(DMACFG, RX_BUF_SIZE, 16, 8)
+FIELD(DMACFG, CRC_ERROR_REPORT, 13, 1)
+FIELD(DMACFG, INF_LAST_DBUF_SIZE_EN, 12, 1)
+FIELD(DMACFG, TX_PBUF_CSUM_OFFLOAD, 11, 1)
+FIELD(DMACFG, TX_PBUF_SIZE, 10, 1)
+FIELD(DMACFG, RX_PBUF_SIZE, 8, 2)
+FIELD(DMACFG, ENDIAN_SWAP_PACKET, 7, 1)
+FIELD(DMACFG, ENDIAN_SWAP_MGNT, 6, 1)
+FIELD(DMACFG, HDR_DATA_SPLIT_EN, 5, 1)
+FIELD(DMACFG, AMBA_BURST_LEN , 0, 5)
+#define GEM_DMACFG_RBUFSZ_MUL  64 /* DMA RX Buffer Size multiplier */
+
 REG32(TXSTATUS, 0x14) /* TX Status reg */
 REG32(RXQBASE, 0x18) /* RX Q Base address reg */
 REG32(TXQBASE, 0x1c) /* TX Q Base address reg */
 REG32(RXSTATUS, 0x20) /* RX Status reg */
 REG32(ISR, 0x24) /* Interrupt Status reg */
@@ -263,17 +283,10 @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
 FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_OFFSET, 7, 2)
 FIELD(TYPE2_COMPARE_0_WORD_1, DISABLE_MASK, 9, 1)
 FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_VLAN_ID, 10, 1)
 
 /*/
-#define GEM_DMACFG_ADDR_64B(1U << 30)
-#define GEM_DMACFG_TX_BD_EXT   (1U << 29)
-#define GEM_DMACFG_RX_BD_EXT   (1U << 28)
-#define GEM_DMACFG_RBUFSZ_M0x00FF /* DMA RX Buffer Size mask */
-#define GEM_DMACFG_RBUFSZ_S16 /* DMA RX Buffer Size shift */
-#define GEM_DMACFG_RBUFSZ_MUL  64 /* DMA RX Buffer Size multiplier */
-#define GEM_DMACFG_TXCSUM_OFFL 0x0800 /* Transmit checksum offload */
 
 #define GEM_TXSTATUS_TXCMPL0x0020 /* Transmit Complete */
 #define GEM_TXSTATUS_USED  0x0001 /* sw owned descriptor encountered */
 
 #define GEM_RXSTATUS_FRMRCVD   0x0002 /* Frame received */
@@ -367,11 +380,11 @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
 
 static inline uint64_t tx_desc_get_buffer(CadenceGEMState *s, uint32_t *desc)
 {
 uint64_t ret = desc[0];
 
-if (s->regs[R_DMACFG] & GEM_DMACFG_ADDR_64B) {
+if (FIELD_EX32(s->regs[R_DMACFG], DMACFG, DMA_ADDR_BUS_WIDTH)) {
 ret |= (uint64_t)desc[2] << 32;
 }
 return ret;
 }
 
@@ -412,25 +425,25 @@ static inline void print_gem_tx_desc(uint32_t *desc, 
uint8_t queue)
 
 static inline uint64_t rx_desc_get_buffer(CadenceGEMState *s, uint32_t *desc)
 {
 uint64_t ret = desc[0] & ~0x3UL;
 
-if (s->regs[R_DMACFG] & GEM_DMACFG_ADDR_64B) {
+if (FIELD_EX32(s->regs[R_DMACFG], DMACFG, DMA_ADDR_BUS_WIDTH)) {
 ret |= (uint64_t)desc[2] << 32;
 }
 return ret;
 }
 
 static inline int gem_get_desc_len(CadenceGEMState *s, bool rx_n_tx)
 {
 int ret = 2;
 
-if (s->regs[R_DMACFG] & GEM_DMACFG_ADDR_64B) {
+if (FIELD_EX32(s->regs[R_DMACFG], DMACFG, DMA_ADDR_BUS_WIDTH)) {
 ret += 2;
 }
-if (s->regs[R_DMACFG] & (rx_n_tx ? GEM_DMACFG_RX_BD_EXT
-   : GEM_DMACFG_TX_BD_EXT)) {
+if (s->regs[R_DMACFG] & (rx_n_tx ? R_DMACFG_RX_BD_EXT_MODE_EN_MASK
+ : R_DMACFG_TX_BD_EXT_MODE_EN_MASK)) {
 ret += 2;
 }
 
 assert(ret <= DESC_MAX_NUM_WORDS);
 return ret;
@@ -940,11 +953,11 @@ static inline uint32_t 
gem_get_rx_queue_base_addr(CadenceGEMState *s, int q)
 
 static hwaddr gem_get_desc_addr(CadenceGEMState *s, bool tx, int q)
 {
 hwaddr desc_addr = 0;
 
-if (s->regs[R_DMACFG] & GEM_DMACFG_ADDR_64B) {
+if (FIELD_EX32(s->regs[R_DMACFG], DMACFG, DMA_ADDR_BUS_WIDTH)) {
 desc_addr = s->regs[tx ? R_TBQPH : R_RBQPH];
 }
 desc_addr <<= 32;
 desc_addr |= tx ? s->tx_desc_addr[q] : s->rx_desc_addr[q];
 return desc_addr;
@@ -1022,12 +1035,13 @@ static ssize_t gem_receive(NetClientState *nc, const 
uint8_t *buf, size_t size)
 rxbuf_offset = FIELD_EX32(s->regs[R_NWCFG], NWCFG, RECV_BUF_OFFSET);
 
 /* The configure size of each receive buffer.  Determines how many
  * buffers needed to hold this packet.
  */
-rxbufsize = ((s->regs[R_DMACFG] & GEM_DMACFG_RBUFSZ_M) >>
- GEM_DMACFG_RBUFSZ_S) * GEM_DMACFG_RBUFSZ_MUL;
+rxbufsize = 

[PATCH v4 4/5] migration: Change ram_dirty_bitmap_reload() retval to bool

2023-10-17 Thread Peter Xu
Now we have a Error** passed into the return path thread stack, which is
even clearer than an int retval.  Change ram_dirty_bitmap_reload() and the
callers to use a bool instead to replace errnos.

Suggested-by: Philippe Mathieu-Daudé 
Signed-off-by: Peter Xu 
---
 migration/ram.h   |  2 +-
 migration/migration.c | 18 +-
 migration/ram.c   | 24 
 3 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/migration/ram.h b/migration/ram.h
index 14ed666d58..af0290f8ab 100644
--- a/migration/ram.h
+++ b/migration/ram.h
@@ -72,7 +72,7 @@ void ramblock_recv_bitmap_set(RAMBlock *rb, void *host_addr);
 void ramblock_recv_bitmap_set_range(RAMBlock *rb, void *host_addr, size_t nr);
 int64_t ramblock_recv_bitmap_send(QEMUFile *file,
   const char *block_name);
-int ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *rb, Error **errp);
+bool ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *rb, Error **errp);
 bool ramblock_page_is_discarded(RAMBlock *rb, ram_addr_t start);
 void postcopy_preempt_shutdown_file(MigrationState *s);
 void *postcopy_preempt_thread(void *opaque);
diff --git a/migration/migration.c b/migration/migration.c
index 0661dad953..dfb8b48dcb 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1843,29 +1843,29 @@ migrate_handle_rp_req_pages(MigrationState *ms, const 
char* rbname,
 ram_save_queue_pages(rbname, start, len, errp);
 }
 
-static int migrate_handle_rp_recv_bitmap(MigrationState *s, char *block_name,
- Error **errp)
+static bool migrate_handle_rp_recv_bitmap(MigrationState *s, char *block_name,
+  Error **errp)
 {
 RAMBlock *block = qemu_ram_block_by_name(block_name);
 
 if (!block) {
 error_setg(errp, "MIG_RP_MSG_RECV_BITMAP has invalid block name '%s'",
block_name);
-return -EINVAL;
+return false;
 }
 
 /* Fetch the received bitmap and refresh the dirty bitmap */
 return ram_dirty_bitmap_reload(s, block, errp);
 }
 
-static int migrate_handle_rp_resume_ack(MigrationState *s,
-uint32_t value, Error **errp)
+static bool migrate_handle_rp_resume_ack(MigrationState *s,
+ uint32_t value, Error **errp)
 {
 trace_source_return_path_thread_resume_ack(value);
 
 if (value != MIGRATION_RESUME_ACK_VALUE) {
 error_setg(errp, "illegal resume_ack value %"PRIu32, value);
-return -1;
+return false;
 }
 
 /* Now both sides are active. */
@@ -1875,7 +1875,7 @@ static int migrate_handle_rp_resume_ack(MigrationState *s,
 /* Notify send thread that time to continue send pages */
 migration_rp_kick(s);
 
-return 0;
+return true;
 }
 
 /*
@@ -2026,14 +2026,14 @@ static void *source_return_path_thread(void *opaque)
 }
 /* Format: len (1B) + idstr (<255B). This ends the idstr. */
 buf[buf[0] + 1] = '\0';
-if (migrate_handle_rp_recv_bitmap(ms, (char *)(buf + 1), )) {
+if (!migrate_handle_rp_recv_bitmap(ms, (char *)(buf + 1), )) {
 goto out;
 }
 break;
 
 case MIG_RP_MSG_RESUME_ACK:
 tmp32 = ldl_be_p(buf);
-if (migrate_handle_rp_resume_ack(ms, tmp32, )) {
+if (!migrate_handle_rp_resume_ack(ms, tmp32, )) {
 goto out;
 }
 break;
diff --git a/migration/ram.c b/migration/ram.c
index 973e872284..ca77444e18 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -4189,10 +4189,11 @@ static int ram_dirty_bitmap_sync_all(MigrationState *s, 
RAMState *rs)
  * Read the received bitmap, revert it as the initial dirty bitmap.
  * This is only used when the postcopy migration is paused but wants
  * to resume from a middle point.
+ *
+ * Returns true if succeeded, false for errors.
  */
-int ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *block, Error **errp)
+bool ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *block, Error **errp)
 {
-int ret = -EINVAL;
 /* from_dst_file is always valid because we're within rp_thread */
 QEMUFile *file = s->rp_state.from_dst_file;
 g_autofree unsigned long *le_bitmap = NULL;
@@ -4206,7 +4207,7 @@ int ram_dirty_bitmap_reload(MigrationState *s, RAMBlock 
*block, Error **errp)
 if (s->state != MIGRATION_STATUS_POSTCOPY_RECOVER) {
 error_setg(errp, "Reload bitmap in incorrect state %s",
MigrationStatus_str(s->state));
-return -EINVAL;
+return false;
 }
 
 /*
@@ -4224,24 +4225,23 @@ int ram_dirty_bitmap_reload(MigrationState *s, RAMBlock 
*block, Error **errp)
 if (size != local_size) {
 error_setg(errp, "ramblock '%s' bitmap size mismatch (0x%"PRIx64
" != 0x%"PRIx64")", block->idstr, size, local_size);
-return 

[PATCH 10/11] hw/net/cadence_gem: perform PHY access on write only

2023-10-17 Thread Luc Michel
The MDIO access is done only on a write to the PHYMNTNC register. A
subsequent read is used to retrieve the result but does not trigger an
MDIO access by itself.

Refactor the PHY access logic to perform all accesses (MDIO reads and
writes) at PHYMNTNC write time.

Signed-off-by: Luc Michel 
---
 hw/net/cadence_gem.c | 56 ++--
 1 file changed, 33 insertions(+), 23 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 4c5fe10316..21146f4242 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -1519,10 +1519,42 @@ static void gem_phy_write(CadenceGEMState *s, unsigned 
reg_num, uint16_t val)
 break;
 }
 s->phy_regs[reg_num] = val;
 }
 
+static void gem_handle_phy_access(CadenceGEMState *s)
+{
+uint32_t val = s->regs[R_PHYMNTNC];
+uint32_t phy_addr, reg_num;
+
+phy_addr = FIELD_EX32(val, PHYMNTNC, PHY_ADDR);
+
+if (phy_addr != s->phy_addr) {
+/* no phy at this address */
+if (FIELD_EX32(val, PHYMNTNC, OP) == MDIO_OP_READ) {
+s->regs[R_PHYMNTNC] = FIELD_DP32(val, PHYMNTNC, DATA, 0x);
+}
+return;
+}
+
+reg_num = FIELD_EX32(val, PHYMNTNC, REG_ADDR);
+
+switch (FIELD_EX32(val, PHYMNTNC, OP)) {
+case MDIO_OP_READ:
+s->regs[R_PHYMNTNC] = FIELD_DP32(val, PHYMNTNC, DATA,
+ gem_phy_read(s, reg_num));
+break;
+
+case MDIO_OP_WRITE:
+gem_phy_write(s, reg_num, val);
+break;
+
+default:
+break; /* only clause 22 operations are supported */
+}
+}
+
 /*
  * gem_read32:
  * Read a GEM register.
  */
 static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size)
@@ -1539,24 +1571,10 @@ static uint64_t gem_read(void *opaque, hwaddr offset, 
unsigned size)
 switch (offset) {
 case R_ISR:
 DB_PRINT("lowering irqs on ISR read\n");
 /* The interrupts get updated at the end of the function. */
 break;
-case R_PHYMNTNC:
-if (FIELD_EX32(retval, PHYMNTNC, OP) == MDIO_OP_READ) {
-uint32_t phy_addr, reg_num;
-
-phy_addr = FIELD_EX32(retval, PHYMNTNC, PHY_ADDR);
-if (phy_addr == s->phy_addr) {
-reg_num = FIELD_EX32(retval, PHYMNTNC, REG_ADDR);
-retval &= 0x;
-retval |= gem_phy_read(s, reg_num);
-} else {
-retval |= 0x; /* No device at this address */
-}
-}
-break;
 }
 
 /* Squash read to clear bits */
 s->regs[offset] &= ~(s->regs_rtc[offset]);
 
@@ -1663,19 +1681,11 @@ static void gem_write(void *opaque, hwaddr offset, 
uint64_t val,
 case R_SPADDR3HI:
 case R_SPADDR4HI:
 s->sar_active[(offset - R_SPADDR1HI) / 2] = true;
 break;
 case R_PHYMNTNC:
-if (FIELD_EX32(val, PHYMNTNC, OP) == MDIO_OP_WRITE) {
-uint32_t phy_addr, reg_num;
-
-phy_addr = FIELD_EX32(val, PHYMNTNC, PHY_ADDR);
-if (phy_addr == s->phy_addr) {
-reg_num = FIELD_EX32(val, PHYMNTNC, REG_ADDR);
-gem_phy_write(s, reg_num, val);
-}
-}
+gem_handle_phy_access(s);
 break;
 }
 
 DB_PRINT("newval: 0x%08x\n", s->regs[offset]);
 }
-- 
2.39.2




[PATCH 07/11] hw/net/cadence_gem: use FIELD to describe IRQ register fields

2023-10-17 Thread Luc Michel
Use de FIELD macro to describe the IRQ related register fields.

Signed-off-by: Luc Michel 
---
 hw/net/cadence_gem.c | 51 +---
 1 file changed, 39 insertions(+), 12 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 0acee1d544..6d084a3b31 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -155,13 +155,46 @@ REG32(RXSTATUS, 0x20) /* RX Status reg */
 FIELD(RXSTATUS, RECEIVE_OVERRUN, 2, 1)
 FIELD(RXSTATUS, FRAME_RECEIVED, 1, 1)
 FIELD(RXSTATUS, BUF_NOT_AVAILABLE, 0, 1)
 
 REG32(ISR, 0x24) /* Interrupt Status reg */
+FIELD(ISR, TX_LOCKUP, 31, 1)
+FIELD(ISR, RX_LOCKUP, 30, 1)
+FIELD(ISR, TSU_TIMER, 29, 1)
+FIELD(ISR, WOL, 28, 1)
+FIELD(ISR, RECV_LPI, 27, 1)
+FIELD(ISR, TSU_SEC_INCR, 26, 1)
+FIELD(ISR, PTP_PDELAY_RESP_XMIT, 25, 1)
+FIELD(ISR, PTP_PDELAY_REQ_XMIT, 24, 1)
+FIELD(ISR, PTP_PDELAY_RESP_RECV, 23, 1)
+FIELD(ISR, PTP_PDELAY_REQ_RECV, 22, 1)
+FIELD(ISR, PTP_SYNC_XMIT, 21, 1)
+FIELD(ISR, PTP_DELAY_REQ_XMIT, 20, 1)
+FIELD(ISR, PTP_SYNC_RECV, 19, 1)
+FIELD(ISR, PTP_DELAY_REQ_RECV, 18, 1)
+FIELD(ISR, PCS_LP_PAGE_RECV, 17, 1)
+FIELD(ISR, PCS_AN_COMPLETE, 16, 1)
+FIELD(ISR, EXT_IRQ, 15, 1)
+FIELD(ISR, PAUSE_FRAME_XMIT, 14, 1)
+FIELD(ISR, PAUSE_TIME_ELAPSED, 13, 1)
+FIELD(ISR, PAUSE_FRAME_RECV, 12, 1)
+FIELD(ISR, RESP_NOT_OK, 11, 1)
+FIELD(ISR, RECV_OVERRUN, 10, 1)
+FIELD(ISR, LINK_CHANGE, 9, 1)
+FIELD(ISR, USXGMII_INT, 8, 1)
+FIELD(ISR, XMIT_COMPLETE, 7, 1)
+FIELD(ISR, AMBA_ERROR, 6, 1)
+FIELD(ISR, RETRY_EXCEEDED, 5, 1)
+FIELD(ISR, XMIT_UNDER_RUN, 4, 1)
+FIELD(ISR, TX_USED, 3, 1)
+FIELD(ISR, RX_USED, 2, 1)
+FIELD(ISR, RECV_COMPLETE, 1, 1)
+FIELD(ISR, MGNT_FRAME_SENT, 0, 1)
 REG32(IER, 0x28) /* Interrupt Enable reg */
 REG32(IDR, 0x2c) /* Interrupt Disable reg */
 REG32(IMR, 0x30) /* Interrupt Mask reg */
+
 REG32(PHYMNTNC, 0x34) /* Phy Maintenance reg */
 REG32(RXPAUSE, 0x38) /* RX Pause Time reg */
 REG32(TXPAUSE, 0x3c) /* TX Pause Time reg */
 REG32(TXPARTIALSF, 0x40) /* TX Partial Store and Forward */
 REG32(RXPARTIALSF, 0x44) /* RX Partial Store and Forward */
@@ -306,16 +339,10 @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
 FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_VLAN_ID, 10, 1)
 
 /*/
 
 
-/* GEM_ISR GEM_IER GEM_IDR GEM_IMR */
-#define GEM_INT_TXCMPL0x0080 /* Transmit Complete */
-#define GEM_INT_AMBA_ERR  0x0040
-#define GEM_INT_TXUSED 0x0008
-#define GEM_INT_RXUSED 0x0004
-#define GEM_INT_RXCMPL0x0002
 
 #define GEM_PHYMNTNC_OP_R  0x2000 /* read operation */
 #define GEM_PHYMNTNC_OP_W  0x1000 /* write operation */
 #define GEM_PHYMNTNC_ADDR  0x0F80 /* Address bits */
 #define GEM_PHYMNTNC_ADDR_SHFT 23
@@ -1002,11 +1029,11 @@ static void gem_get_rx_desc(CadenceGEMState *s, int q)
 
 /* Descriptor owned by software ? */
 if (rx_desc_get_ownership(s->rx_desc[q]) == 1) {
 DB_PRINT("descriptor 0x%" HWADDR_PRIx " owned by sw.\n", desc_addr);
 s->regs[R_RXSTATUS] |= R_RXSTATUS_BUF_NOT_AVAILABLE_MASK;
-gem_set_isr(s, q, GEM_INT_RXUSED);
+gem_set_isr(s, q, R_ISR_RX_USED_MASK);
 /* Handle interrupt consequences */
 gem_update_int_status(s);
 }
 }
 
@@ -1102,11 +1129,11 @@ static ssize_t gem_receive(NetClientState *nc, const 
uint8_t *buf, size_t size)
 /* Find which queue we are targeting */
 q = get_queue_from_screen(s, rxbuf_ptr, rxbufsize);
 
 if (size > gem_get_max_buf_len(s, false)) {
 qemu_log_mask(LOG_GUEST_ERROR, "rx frame too long\n");
-gem_set_isr(s, q, GEM_INT_AMBA_ERR);
+gem_set_isr(s, q, R_ISR_AMBA_ERROR_MASK);
 return -1;
 }
 
 while (bytes_to_copy) {
 hwaddr desc_addr;
@@ -1179,11 +1206,11 @@ static ssize_t gem_receive(NetClientState *nc, const 
uint8_t *buf, size_t size)
 
 /* Count it */
 gem_receive_updatestats(s, buf, size);
 
 s->regs[R_RXSTATUS] |= R_RXSTATUS_FRAME_RECEIVED_MASK;
-gem_set_isr(s, q, GEM_INT_RXCMPL);
+gem_set_isr(s, q, R_ISR_RECV_COMPLETE_MASK);
 
 /* Handle interrupt consequences */
 gem_update_int_status(s);
 
 return size;
@@ -1292,11 +1319,11 @@ static void gem_transmit(CadenceGEMState *s)
(p - s->tx_packet)) {
 qemu_log_mask(LOG_GUEST_ERROR, "TX descriptor @ 0x%" \
  HWADDR_PRIx " too large: size 0x%x space 0x%zx\n",
  packet_desc_addr, tx_desc_get_length(desc),
  gem_get_max_buf_len(s, true) - (p - s->tx_packet));
-gem_set_isr(s, q, GEM_INT_AMBA_ERR);
+gem_set_isr(s, q, R_ISR_AMBA_ERROR_MASK);
 break;
 }
 
 /* Gather this fragment of the packet from "dma memory" to our
  * 

[PATCH 06/11] hw/net/cadence_gem: use FIELD to describe [TX|RX]STATUS register fields

2023-10-17 Thread Luc Michel
Use de FIELD macro to describe the TXSTATUS and RXSTATUS register
fields.

Signed-off-by: Luc Michel 
---
 hw/net/cadence_gem.c | 34 +-
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 5c386adff2..0acee1d544 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -130,13 +130,34 @@ REG32(DMACFG, 0x10) /* DMA Control reg */
 FIELD(DMACFG, HDR_DATA_SPLIT_EN, 5, 1)
 FIELD(DMACFG, AMBA_BURST_LEN , 0, 5)
 #define GEM_DMACFG_RBUFSZ_MUL  64 /* DMA RX Buffer Size multiplier */
 
 REG32(TXSTATUS, 0x14) /* TX Status reg */
+FIELD(TXSTATUS, TX_USED_BIT_READ_MIDFRAME, 12, 1)
+FIELD(TXSTATUS, TX_FRAME_TOO_LARGE, 11, 1)
+FIELD(TXSTATUS, TX_DMA_LOCKUP, 10, 1)
+FIELD(TXSTATUS, TX_MAC_LOCKUP, 9, 1)
+FIELD(TXSTATUS, RESP_NOT_OK, 8, 1)
+FIELD(TXSTATUS, LATE_COLLISION, 7, 1)
+FIELD(TXSTATUS, TRANSMIT_UNDER_RUN, 6, 1)
+FIELD(TXSTATUS, TRANSMIT_COMPLETE, 5, 1)
+FIELD(TXSTATUS, AMBA_ERROR, 4, 1)
+FIELD(TXSTATUS, TRANSMIT_GO, 3, 1)
+FIELD(TXSTATUS, RETRY_LIMIT, 2, 1)
+FIELD(TXSTATUS, COLLISION, 1, 1)
+FIELD(TXSTATUS, USED_BIT_READ, 0, 1)
+
 REG32(RXQBASE, 0x18) /* RX Q Base address reg */
 REG32(TXQBASE, 0x1c) /* TX Q Base address reg */
 REG32(RXSTATUS, 0x20) /* RX Status reg */
+FIELD(RXSTATUS, RX_DMA_LOCKUP, 5, 1)
+FIELD(RXSTATUS, RX_MAC_LOCKUP, 4, 1)
+FIELD(RXSTATUS, RESP_NOT_OK, 3, 1)
+FIELD(RXSTATUS, RECEIVE_OVERRUN, 2, 1)
+FIELD(RXSTATUS, FRAME_RECEIVED, 1, 1)
+FIELD(RXSTATUS, BUF_NOT_AVAILABLE, 0, 1)
+
 REG32(ISR, 0x24) /* Interrupt Status reg */
 REG32(IER, 0x28) /* Interrupt Enable reg */
 REG32(IDR, 0x2c) /* Interrupt Disable reg */
 REG32(IMR, 0x30) /* Interrupt Mask reg */
 REG32(PHYMNTNC, 0x34) /* Phy Maintenance reg */
@@ -284,15 +305,10 @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
 FIELD(TYPE2_COMPARE_0_WORD_1, DISABLE_MASK, 9, 1)
 FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_VLAN_ID, 10, 1)
 
 /*/
 
-#define GEM_TXSTATUS_TXCMPL0x0020 /* Transmit Complete */
-#define GEM_TXSTATUS_USED  0x0001 /* sw owned descriptor encountered */
-
-#define GEM_RXSTATUS_FRMRCVD   0x0002 /* Frame received */
-#define GEM_RXSTATUS_NOBUF 0x0001 /* Buffer unavailable */
 
 /* GEM_ISR GEM_IER GEM_IDR GEM_IMR */
 #define GEM_INT_TXCMPL0x0080 /* Transmit Complete */
 #define GEM_INT_AMBA_ERR  0x0040
 #define GEM_INT_TXUSED 0x0008
@@ -985,11 +1001,11 @@ static void gem_get_rx_desc(CadenceGEMState *s, int q)
sizeof(uint32_t) * gem_get_desc_len(s, true));
 
 /* Descriptor owned by software ? */
 if (rx_desc_get_ownership(s->rx_desc[q]) == 1) {
 DB_PRINT("descriptor 0x%" HWADDR_PRIx " owned by sw.\n", desc_addr);
-s->regs[R_RXSTATUS] |= GEM_RXSTATUS_NOBUF;
+s->regs[R_RXSTATUS] |= R_RXSTATUS_BUF_NOT_AVAILABLE_MASK;
 gem_set_isr(s, q, GEM_INT_RXUSED);
 /* Handle interrupt consequences */
 gem_update_int_status(s);
 }
 }
@@ -1162,11 +1178,11 @@ static ssize_t gem_receive(NetClientState *nc, const 
uint8_t *buf, size_t size)
 }
 
 /* Count it */
 gem_receive_updatestats(s, buf, size);
 
-s->regs[R_RXSTATUS] |= GEM_RXSTATUS_FRMRCVD;
+s->regs[R_RXSTATUS] |= R_RXSTATUS_FRAME_RECEIVED_MASK;
 gem_set_isr(s, q, GEM_INT_RXCMPL);
 
 /* Handle interrupt consequences */
 gem_update_int_status(s);
 
@@ -1313,11 +1329,11 @@ static void gem_transmit(CadenceGEMState *s)
 s->tx_desc_addr[q] = packet_desc_addr +
  4 * gem_get_desc_len(s, false);
 }
 DB_PRINT("TX descriptor next: 0x%08x\n", s->tx_desc_addr[q]);
 
-s->regs[R_TXSTATUS] |= GEM_TXSTATUS_TXCMPL;
+s->regs[R_TXSTATUS] |= R_TXSTATUS_TRANSMIT_COMPLETE_MASK;
 gem_set_isr(s, q, GEM_INT_TXCMPL);
 
 /* Handle interrupt consequences */
 gem_update_int_status(s);
 
@@ -1361,11 +1377,11 @@ static void gem_transmit(CadenceGEMState *s)
MEMTXATTRS_UNSPECIFIED, desc,
sizeof(uint32_t) * gem_get_desc_len(s, false));
 }
 
 if (tx_desc_get_used(desc)) {
-s->regs[R_TXSTATUS] |= GEM_TXSTATUS_USED;
+s->regs[R_TXSTATUS] |= R_TXSTATUS_USED_BIT_READ_MASK;
 /* IRQ TXUSED is defined only for queue 0 */
 if (q == 0) {
 gem_set_isr(s, 0, GEM_INT_TXUSED);
 }
 gem_update_int_status(s);
-- 
2.39.2




[PATCH 01/11] hw/net/cadence_gem: use REG32 macro for register definitions

2023-10-17 Thread Luc Michel
Replace register defines with the REG32 macro from registerfields.h in
the Cadence GEM device.

Signed-off-by: Luc Michel 
---
 hw/net/cadence_gem.c | 527 +--
 1 file changed, 261 insertions(+), 266 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index f445d8bb5e..0e5744ecd7 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -26,10 +26,11 @@
 #include  /* For crc32 */
 
 #include "hw/irq.h"
 #include "hw/net/cadence_gem.h"
 #include "hw/qdev-properties.h"
+#include "hw/registerfields.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
 #include "sysemu/dma.h"
@@ -42,151 +43,146 @@
 qemu_log(": %s: ", __func__); \
 qemu_log(__VA_ARGS__); \
 } \
 } while (0)
 
-#define GEM_NWCTRL(0x / 4) /* Network Control reg */
-#define GEM_NWCFG (0x0004 / 4) /* Network Config reg */
-#define GEM_NWSTATUS  (0x0008 / 4) /* Network Status reg */
-#define GEM_USERIO(0x000C / 4) /* User IO reg */
-#define GEM_DMACFG(0x0010 / 4) /* DMA Control reg */
-#define GEM_TXSTATUS  (0x0014 / 4) /* TX Status reg */
-#define GEM_RXQBASE   (0x0018 / 4) /* RX Q Base address reg */
-#define GEM_TXQBASE   (0x001C / 4) /* TX Q Base address reg */
-#define GEM_RXSTATUS  (0x0020 / 4) /* RX Status reg */
-#define GEM_ISR   (0x0024 / 4) /* Interrupt Status reg */
-#define GEM_IER   (0x0028 / 4) /* Interrupt Enable reg */
-#define GEM_IDR   (0x002C / 4) /* Interrupt Disable reg */
-#define GEM_IMR   (0x0030 / 4) /* Interrupt Mask reg */
-#define GEM_PHYMNTNC  (0x0034 / 4) /* Phy Maintenance reg */
-#define GEM_RXPAUSE   (0x0038 / 4) /* RX Pause Time reg */
-#define GEM_TXPAUSE   (0x003C / 4) /* TX Pause Time reg */
-#define GEM_TXPARTIALSF   (0x0040 / 4) /* TX Partial Store and Forward */
-#define GEM_RXPARTIALSF   (0x0044 / 4) /* RX Partial Store and Forward */
-#define GEM_JUMBO_MAX_LEN (0x0048 / 4) /* Max Jumbo Frame Size */
-#define GEM_HASHLO(0x0080 / 4) /* Hash Low address reg */
-#define GEM_HASHHI(0x0084 / 4) /* Hash High address reg */
-#define GEM_SPADDR1LO (0x0088 / 4) /* Specific addr 1 low reg */
-#define GEM_SPADDR1HI (0x008C / 4) /* Specific addr 1 high reg */
-#define GEM_SPADDR2LO (0x0090 / 4) /* Specific addr 2 low reg */
-#define GEM_SPADDR2HI (0x0094 / 4) /* Specific addr 2 high reg */
-#define GEM_SPADDR3LO (0x0098 / 4) /* Specific addr 3 low reg */
-#define GEM_SPADDR3HI (0x009C / 4) /* Specific addr 3 high reg */
-#define GEM_SPADDR4LO (0x00A0 / 4) /* Specific addr 4 low reg */
-#define GEM_SPADDR4HI (0x00A4 / 4) /* Specific addr 4 high reg */
-#define GEM_TIDMATCH1 (0x00A8 / 4) /* Type ID1 Match reg */
-#define GEM_TIDMATCH2 (0x00AC / 4) /* Type ID2 Match reg */
-#define GEM_TIDMATCH3 (0x00B0 / 4) /* Type ID3 Match reg */
-#define GEM_TIDMATCH4 (0x00B4 / 4) /* Type ID4 Match reg */
-#define GEM_WOLAN (0x00B8 / 4) /* Wake on LAN reg */
-#define GEM_IPGSTRETCH(0x00BC / 4) /* IPG Stretch reg */
-#define GEM_SVLAN (0x00C0 / 4) /* Stacked VLAN reg */
-#define GEM_MODID (0x00FC / 4) /* Module ID reg */
-#define GEM_OCTTXLO   (0x0100 / 4) /* Octets transmitted Low reg */
-#define GEM_OCTTXHI   (0x0104 / 4) /* Octets transmitted High reg */
-#define GEM_TXCNT (0x0108 / 4) /* Error-free Frames transmitted */
-#define GEM_TXBCNT(0x010C / 4) /* Error-free Broadcast Frames */
-#define GEM_TXMCNT(0x0110 / 4) /* Error-free Multicast Frame */
-#define GEM_TXPAUSECNT(0x0114 / 4) /* Pause Frames Transmitted */
-#define GEM_TX64CNT   (0x0118 / 4) /* Error-free 64 TX */
-#define GEM_TX65CNT   (0x011C / 4) /* Error-free 65-127 TX */
-#define GEM_TX128CNT  (0x0120 / 4) /* Error-free 128-255 TX */
-#define GEM_TX256CNT  (0x0124 / 4) /* Error-free 256-511 */
-#define GEM_TX512CNT  (0x0128 / 4) /* Error-free 512-1023 TX */
-#define GEM_TX1024CNT (0x012C / 4) /* Error-free 1024-1518 TX */
-#define GEM_TX1519CNT (0x0130 / 4) /* Error-free larger than 1519 TX */
-#define GEM_TXURUNCNT (0x0134 / 4) /* TX under run error counter */
-#define GEM_SINGLECOLLCNT (0x0138 / 4) /* Single Collision Frames */
-#define GEM_MULTCOLLCNT   (0x013C / 4) /* Multiple Collision Frames */
-#define GEM_EXCESSCOLLCNT (0x0140 / 4) /* Excessive Collision Frames */
-#define GEM_LATECOLLCNT   (0x0144 / 4) /* Late Collision Frames */
-#define GEM_DEFERTXCNT(0x0148 / 4) /* Deferred Transmission Frames */
-#define GEM_CSENSECNT (0x014C / 4) /* Carrier Sense Error Counter */
-#define GEM_OCTRXLO   (0x0150 / 4) /* Octets Received 

Re: [PATCH] MAINTAINERS: Add hw/input/lasips2.c to the HPPA machine section

2023-10-17 Thread Mark Cave-Ayland

On 17/10/2023 16:19, Thomas Huth wrote:


hw/input/lasips2.c and the corresponding header include/hw/input/lasips2.h
are only used by the HPPA machine, so add them to the corresponding section
in the MAINTAINERS file.

Signed-off-by: Thomas Huth 
---
  MAINTAINERS | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b0416d473e..a0ad23b9b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1199,9 +1199,11 @@ R: Helge Deller 
  S: Odd Fixes
  F: configs/devices/hppa-softmmu/default.mak
  F: hw/hppa/
+F: hw/input/lasips2.c
  F: hw/net/*i82596*
  F: hw/misc/lasi.c
  F: hw/pci-host/dino.c
+F: include/hw/input/lasips2.h
  F: include/hw/misc/lasi.h
  F: include/hw/net/lasi_82596.h
  F: include/hw/pci-host/dino.h


Reviewed-by: Mark Cave-Ayland 


ATB,

Mark.




Re: [PATCH v2 02/11] pci_ids/tulip: Add PCI vendor ID for HP and use it in tulip

2023-10-17 Thread BALATON Zoltan

On Tue, 17 Oct 2023, Helge Deller wrote:

On 10/17/23 21:19, BALATON Zoltan wrote:

On Tue, 17 Oct 2023, Helge Deller wrote:

On 10/17/23 18:13, BALATON Zoltan wrote:

On Tue, 17 Oct 2023, del...@kernel.org wrote:

From: Helge Deller 

Signed-off-by: Helge Deller 
---
hw/net/tulip.c   | 2 +-
include/hw/pci/pci_ids.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/net/tulip.c b/hw/net/tulip.c
index 915e5fb595..11d866e431 100644
--- a/hw/net/tulip.c
+++ b/hw/net/tulip.c
@@ -1020,7 +1020,7 @@ static void tulip_class_init(ObjectClass *klass, 
void *data)

    k->exit = pci_tulip_exit;
    k->vendor_id = PCI_VENDOR_ID_DEC;
    k->device_id = PCI_DEVICE_ID_DEC_21143;
-    k->subsystem_vendor_id = 0x103c;
+    k->subsystem_vendor_id = PCI_VENDOR_ID_HP;
    k->subsystem_id = 0x104f;
    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
    dc->vmsd = _pci_tulip;
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index 85469b9b53..3c0e72df0e 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -171,6 +171,8 @@
#define PCI_VENDOR_ID_DEC    0x1011
#define PCI_DEVICE_ID_DEC_21143  0x0019

+#define PCI_VENDOR_ID_HP 0x103c
+


Did not notice this in first round, sorry. These seems to be sorted
(there's a comment further up about that) so this should be between
AMD and TI a bit more down.


The list isn't sorted at all. I think the comment just wants to


It is still mostly sorted except where people did not get how. Try

grep PCI_VENDOR_ID_ pci_ids.h


say that you should mention the vendor before the devices.


I think it says that PCI_VENDOR_IDs should be sorted and then DEVICE_IDs 
within them should also be sorted but device IDs intervene VENDOR_IDs so 
the sorting of VENDOR_IDs may not be obvious at first sight.



Anyway, as the list currently is, there are multiple positions
where HP could be added...


Yes, some IDs already break this sorting but we could still avoid breaking 
it more. [...]


... that's why I added "HP" it after "DEC" :-)


But it should be sorted by ID number not name that's why it should be 
between AMD 0x1022 and TI 0x104c.


Regards,
BALATON Zoltan

Re: [PATCH 7/7] hw/usb: Declare link using static DEFINE_PROP_LINK() macro

2023-10-17 Thread Mark Cave-Ayland

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


Pull the 'dma' property to the core XHCI type, declare
its link statically using DEFINE_PROP_LINK().

Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/usb/hcd-xhci-sysbus.c | 4 
  hw/usb/hcd-xhci.c| 2 ++
  2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/usb/hcd-xhci-sysbus.c b/hw/usb/hcd-xhci-sysbus.c
index faf57b4797..15983d0b96 100644
--- a/hw/usb/hcd-xhci-sysbus.c
+++ b/hw/usb/hcd-xhci-sysbus.c
@@ -60,10 +60,6 @@ static void xhci_sysbus_instance_init(Object *obj)
  object_initialize_child(obj, "xhci-core", >xhci, TYPE_XHCI);
  qdev_alias_all_properties(DEVICE(>xhci), obj);
  
-object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,

- (Object **)>xhci.dma_mr,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_STRONG);
  s->xhci.intr_update = NULL;
  s->xhci.intr_raise = xhci_sysbus_intr_raise;
  }
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 4b60114207..012a6f3644 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3638,6 +3638,8 @@ static Property xhci_properties[] = {
  DEFINE_PROP_UINT32("p3",XHCIState, numports_3, 4),
  DEFINE_PROP_LINK("host",XHCIState, hostOpaque, TYPE_DEVICE,
   DeviceState *),
+DEFINE_PROP_LINK("dma", XHCIState, dma_mr,
+ TYPE_MEMORY_REGION, MemoryRegion *),
  DEFINE_PROP_END_OF_LIST(),
  };


I'm slightly unsure about this one: does pulling the "dma" property into the core 
type cause any issues if the property is left unset for any non-sysbus xhci users?



ATB,

Mark.




Re: [PATCH 6/7] hw/net: Declare link using static DEFINE_PROP_LINK() macro

2023-10-17 Thread Mark Cave-Ayland

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


Declare link statically using DEFINE_PROP_LINK().

Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/net/cadence_gem.c | 7 ++-
  1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index f445d8bb5e..37e209cda6 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -1654,11 +1654,6 @@ static void gem_init(Object *obj)
"enet", sizeof(s->regs));
  
  sysbus_init_mmio(SYS_BUS_DEVICE(dev), >iomem);

-
-object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
- (Object **)>dma_mr,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_STRONG);
  }
  
  static const VMStateDescription vmstate_cadence_gem = {

@@ -1691,6 +1686,8 @@ static Property gem_properties[] = {
num_type2_screeners, 4),
  DEFINE_PROP_UINT16("jumbo-max-len", CadenceGEMState,
 jumbo_max_len, 10240),
+DEFINE_PROP_LINK("dma", CadenceGEMState, dma_mr,
+ TYPE_MEMORY_REGION, MemoryRegion *),
  DEFINE_PROP_END_OF_LIST(),
  };


Reviewed-by: Mark Cave-Ayland 


ATB,

Mark.




Re: [PATCH 5/7] hw/dma: Declare link using static DEFINE_PROP_LINK() macro

2023-10-17 Thread Mark Cave-Ayland

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


Declare link statically using DEFINE_PROP_LINK().

Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/dma/xilinx_axidma.c |  6 ++
  hw/dma/xlnx-zdma.c |  7 ++-
  hw/dma/xlnx_csu_dma.c  | 13 -
  3 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index 12c90267df..0ae056ed06 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -577,10 +577,6 @@ static void xilinx_axidma_init(Object *obj)
  object_initialize_child(OBJECT(s), "axistream-control-connected-target",
  >rx_control_dev,
  TYPE_XILINX_AXI_DMA_CONTROL_STREAM);
-object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
- (Object **)>dma_mr,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_STRONG);
  
  sysbus_init_irq(sbd, >streams[0].irq);

  sysbus_init_irq(sbd, >streams[1].irq);
@@ -596,6 +592,8 @@ static Property axidma_properties[] = {
   tx_data_dev, TYPE_STREAM_SINK, StreamSink *),
  DEFINE_PROP_LINK("axistream-control-connected", XilinxAXIDMA,
   tx_control_dev, TYPE_STREAM_SINK, StreamSink *),
+DEFINE_PROP_LINK("dma", XilinxAXIDMA, dma_mr,
+ TYPE_MEMORY_REGION, MemoryRegion *),
  DEFINE_PROP_END_OF_LIST(),
  };
  
diff --git a/hw/dma/xlnx-zdma.c b/hw/dma/xlnx-zdma.c

index 4eb7f66e9f..84c0083013 100644
--- a/hw/dma/xlnx-zdma.c
+++ b/hw/dma/xlnx-zdma.c
@@ -795,11 +795,6 @@ static void zdma_init(Object *obj)
TYPE_XLNX_ZDMA, ZDMA_R_MAX * 4);
  sysbus_init_mmio(sbd, >iomem);
  sysbus_init_irq(sbd, >irq_zdma_ch_imr);
-
-object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
- (Object **)>dma_mr,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_STRONG);
  }
  
  static const VMStateDescription vmstate_zdma = {

@@ -817,6 +812,8 @@ static const VMStateDescription vmstate_zdma = {
  
  static Property zdma_props[] = {

  DEFINE_PROP_UINT32("bus-width", XlnxZDMA, cfg.bus_width, 64),
+DEFINE_PROP_LINK("dma", XlnxZDMA, dma_mr,
+ TYPE_MEMORY_REGION, MemoryRegion *),
  DEFINE_PROP_END_OF_LIST(),
  };
  
diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c

index 88002698a1..e89089821a 100644
--- a/hw/dma/xlnx_csu_dma.c
+++ b/hw/dma/xlnx_csu_dma.c
@@ -702,6 +702,10 @@ static Property xlnx_csu_dma_properties[] = {
   * which channel the device is connected to.
   */
  DEFINE_PROP_BOOL("is-dst", XlnxCSUDMA, is_dst, true),
+DEFINE_PROP_LINK("stream-connected-dma", XlnxCSUDMA, tx_dev,
+ TYPE_STREAM_SINK, StreamSink *),
+DEFINE_PROP_LINK("dma", XlnxCSUDMA, dma_mr,
+ TYPE_MEMORY_REGION, MemoryRegion *),
  DEFINE_PROP_END_OF_LIST(),
  };
  
@@ -728,15 +732,6 @@ static void xlnx_csu_dma_init(Object *obj)
  
  memory_region_init(>iomem, obj, TYPE_XLNX_CSU_DMA,

 XLNX_CSU_DMA_R_MAX * 4);
-
-object_property_add_link(obj, "stream-connected-dma", TYPE_STREAM_SINK,
- (Object **)>tx_dev,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_STRONG);
-object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
- (Object **)>dma_mr,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_STRONG);
  }
  
  static const TypeInfo xlnx_csu_dma_info = {


Reviewed-by: Mark Cave-Ayland 


ATB,

Mark.




Re: [PATCH] hvf: Enable 1G page support

2023-10-17 Thread Alexander Graf



On 21.04.23 00:52, Alexander Graf wrote:

Hvf on x86 only supported 2MiB large pages, but never bothered to strip
out the 1GiB page size capability from -cpu host. With QEMU 8.0.0 this
became a problem because OVMF started to use 1GiB pages by default.

Let's just unconditionally add 1GiB page walk support to the walker.

With this fix applied, I can successfully run OVMF again.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1603
Signed-off-by: Alexander Graf 
Reported-by: Akihiro Suda 
Reported-by: Philippe Mathieu-Daudé 



Ping. Anyone willing to pick this up? :)


Alex





Re: [PATCH 4/7] hw/scsi/virtio-scsi: Use VIRTIO_SCSI_COMMON() macro

2023-10-17 Thread Mark Cave-Ayland

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


Access QOM parent with the proper QOM VIRTIO_SCSI_COMMON() macro.

Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/scsi/virtio-scsi.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 45b95ea070..fa53f0902c 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -761,7 +761,7 @@ static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq *req)
  
  static int virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)

  {
-VirtIOSCSICommon *vs = >parent_obj;
+VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
  SCSIDevice *d;
  int rc;


Reviewed-by: Mark Cave-Ayland 


ATB,

Mark.




Re: [PATCH 3/7] hw/display/virtio-gpu: Use VIRTIO_DEVICE() macro

2023-10-17 Thread Mark Cave-Ayland

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


Access QOM parent with the proper QOM VIRTIO_DEVICE() macro.

Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/display/virtio-gpu.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 93857ad523..51cb517999 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1132,7 +1132,7 @@ static void virtio_gpu_ctrl_bh(void *opaque)
  VirtIOGPU *g = opaque;
  VirtIOGPUClass *vgc = VIRTIO_GPU_GET_CLASS(g);
  
-vgc->handle_ctrl(>parent_obj.parent_obj, g->ctrl_vq);

+vgc->handle_ctrl(VIRTIO_DEVICE(g), g->ctrl_vq);
  }
  
  static void virtio_gpu_handle_cursor(VirtIODevice *vdev, VirtQueue *vq)


Reviewed-by: Mark Cave-Ayland 


ATB,

Mark.




Re: [PATCH 2/7] hw/block/vhost-user-blk: Use DEVICE() / VIRTIO_DEVICE() macros

2023-10-17 Thread Mark Cave-Ayland

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


Access QOM parent with the proper QOM [VIRTIO_]DEVICE() macros.

Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/block/vhost-user-blk.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index eecf3f7a81..4b37e26120 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -405,7 +405,7 @@ static void vhost_user_blk_event(void *opaque, QEMUChrEvent 
event)
  
  static int vhost_user_blk_realize_connect(VHostUserBlk *s, Error **errp)

  {
-DeviceState *dev = >parent_obj.parent_obj;
+DeviceState *dev = DEVICE(s);
  int ret;
  
  s->connected = false;

@@ -423,7 +423,7 @@ static int vhost_user_blk_realize_connect(VHostUserBlk *s, 
Error **errp)
  assert(s->connected);
  
  ret = vhost_dev_get_config(>dev, (uint8_t *)>blkcfg,

-   s->parent_obj.config_len, errp);
+   VIRTIO_DEVICE(s)->config_len, errp);
  if (ret < 0) {
  qemu_chr_fe_disconnect(>chardev);
  vhost_dev_cleanup(>dev);


Reviewed-by: Mark Cave-Ayland 


ATB,

Mark.




Re: [PATCH v3 0/8] qemu-img: rebase: add compression support

2023-10-17 Thread Kevin Wolf
Am 19.09.2023 um 18:57 hat Andrey Drobyshev geschrieben:
> v2 --> v3:
>  * Patch 3/8: fixed logic in the if statement, so that we align on blk
>when blk_old_backing == NULL;
>  * Patch 4/8: comment fix;
>  * Patch 5/8: comment fix; dropped redundant "if (blk_new_backing)"
>statements.
> 
> v2: https://lists.nongnu.org/archive/html/qemu-block/2023-09/msg00448.html
> 
> Andrey Drobyshev (8):
>   qemu-img: rebase: stop when reaching EOF of old backing file
>   qemu-iotests: 024: add rebasing test case for overlay_size >
> backing_size
>   qemu-img: rebase: use backing files' BlockBackend for buffer alignment
>   qemu-img: add chunk size parameter to compare_buffers()
>   qemu-img: rebase: avoid unnecessary COW operations
>   iotests/{024, 271}: add testcases for qemu-img rebase
>   qemu-img: add compression option to rebase subcommand
>   iotests: add tests for "qemu-img rebase" with compression

Thanks, applied to the block branch.

Kevin




Re: [PATCH] hw/audio/pcspk: Inline pcspk_init()

2023-10-17 Thread Mark Cave-Ayland

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


pcspk_init() is a legacy init function, inline and remove it.

Signed-off-by: Philippe Mathieu-Daudé 
---
  include/hw/audio/pcspk.h | 10 --
  hw/i386/pc.c |  3 ++-
  hw/isa/i82378.c  |  5 -
  hw/mips/jazz.c   |  5 -
  4 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/include/hw/audio/pcspk.h b/include/hw/audio/pcspk.h
index 9506179587..6be75a6b86 100644
--- a/include/hw/audio/pcspk.h
+++ b/include/hw/audio/pcspk.h
@@ -25,16 +25,6 @@
  #ifndef HW_PCSPK_H
  #define HW_PCSPK_H
  
-#include "hw/isa/isa.h"

-#include "hw/qdev-properties.h"
-#include "qapi/error.h"
-
  #define TYPE_PC_SPEAKER "isa-pcspk"
  
-static inline void pcspk_init(ISADevice *isadev, ISABus *bus, ISADevice *pit)

-{
-object_property_set_link(OBJECT(isadev), "pit", OBJECT(pit), NULL);
-isa_realize_and_unref(isadev, bus, _fatal);
-}
-
  #endif /* HW_PCSPK_H */
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index bb3854d1d0..3d0b53a583 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1283,7 +1283,8 @@ void pc_basic_device_init(struct PCMachineState *pcms,
  /* connect PIT to output control line of the HPET */
  qdev_connect_gpio_out(hpet, 0, qdev_get_gpio_in(DEVICE(pit), 0));
  }
-pcspk_init(pcms->pcspk, isa_bus, pit);
+object_property_set_link(OBJECT(pcms->pcspk), "pit", OBJECT(pit), 
NULL);
+isa_realize_and_unref(pcms->pcspk, isa_bus, _fatal);
  }
  
  /* Super I/O */

diff --git a/hw/isa/i82378.c b/hw/isa/i82378.c
index 63e0857208..9474bf994c 100644
--- a/hw/isa/i82378.c
+++ b/hw/isa/i82378.c
@@ -67,6 +67,7 @@ static void i82378_realize(PCIDevice *pci, Error **errp)
  uint8_t *pci_conf;
  ISABus *isabus;
  ISADevice *pit;
+ISADevice *pcspk;
  
  pci_conf = pci->config;

  pci_set_word(pci_conf + PCI_COMMAND,
@@ -102,7 +103,9 @@ static void i82378_realize(PCIDevice *pci, Error **errp)
  pit = i8254_pit_init(isabus, 0x40, 0, NULL);
  
  /* speaker */

-pcspk_init(isa_new(TYPE_PC_SPEAKER), isabus, pit);
+pcspk = isa_new(TYPE_PC_SPEAKER);
+object_property_set_link(OBJECT(pcspk), "pit", OBJECT(pit), NULL);
+isa_realize_and_unref(pcspk, isabus, _fatal);
  
  /* 2 82C37 (dma) */

  isa_create_simple(isabus, "i82374");
diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c
index c32d2b0b0a..aac851747c 100644
--- a/hw/mips/jazz.c
+++ b/hw/mips/jazz.c
@@ -177,6 +177,7 @@ static void mips_jazz_init(MachineState *machine,
  SysBusDevice *sysbus;
  ISABus *isa_bus;
  ISADevice *pit;
+ISADevice *pcspk;
  DriveInfo *fds[MAX_FD];
  MemoryRegion *bios = g_new(MemoryRegion, 1);
  MemoryRegion *bios2 = g_new(MemoryRegion, 1);
@@ -279,7 +280,9 @@ static void mips_jazz_init(MachineState *machine,
  isa_bus_register_input_irqs(isa_bus, i8259);
  i8257_dma_init(isa_bus, 0);
  pit = i8254_pit_init(isa_bus, 0x40, 0, NULL);
-pcspk_init(isa_new(TYPE_PC_SPEAKER), isa_bus, pit);
+pcspk = isa_new(TYPE_PC_SPEAKER);
+object_property_set_link(OBJECT(pcspk), "pit", OBJECT(pit), NULL);
+isa_realize_and_unref(pcspk, isa_bus, _fatal);
  
  /* Video card */

  switch (jazz_model) {


Possibly you might want to pass errp instead of NULL for the last parameter of 
object_property_set_link() in i82378_realize()? But regardless:


Reviewed-by: Mark Cave-Ayland 


ATB,

Mark.




Re: [PATCH] ui/input: Constify QemuInputHandler structure

2023-10-17 Thread Mark Cave-Ayland

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


Access to QemuInputHandlerState::handler are read-only.

Signed-off-by: Philippe Mathieu-Daudé 
---
  include/hw/virtio/virtio-input.h | 2 +-
  include/ui/input.h   | 2 +-
  chardev/msmouse.c| 2 +-
  chardev/wctablet.c   | 2 +-
  hw/char/escc.c   | 2 +-
  hw/display/xenfb.c   | 6 +++---
  hw/input/adb-kbd.c   | 2 +-
  hw/input/hid.c   | 6 +++---
  hw/input/ps2.c   | 4 ++--
  hw/input/virtio-input-hid.c  | 8 
  ui/input-legacy.c| 2 +-
  ui/input.c   | 4 ++--
  ui/vdagent.c | 2 +-
  13 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/include/hw/virtio/virtio-input.h b/include/hw/virtio/virtio-input.h
index 08f1591424..a6c9703644 100644
--- a/include/hw/virtio/virtio-input.h
+++ b/include/hw/virtio/virtio-input.h
@@ -84,7 +84,7 @@ struct VirtIOInputHID {
  VirtIOInput   parent_obj;
  char  *display;
  uint32_t  head;
-QemuInputHandler  *handler;
+const QemuInputHandler*handler;
  QemuInputHandlerState *hs;
  int   ledstate;
  bool  wheel_axis;
diff --git a/include/ui/input.h b/include/ui/input.h
index 24d8e4579e..8f9aac562e 100644
--- a/include/ui/input.h
+++ b/include/ui/input.h
@@ -30,7 +30,7 @@ struct QemuInputHandler {
  };
  
  QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev,

-   QemuInputHandler *handler);
+const QemuInputHandler *handler);
  void qemu_input_handler_activate(QemuInputHandlerState *s);
  void qemu_input_handler_deactivate(QemuInputHandlerState *s);
  void qemu_input_handler_unregister(QemuInputHandlerState *s);
diff --git a/chardev/msmouse.c b/chardev/msmouse.c
index ab8fe981d6..a774c397b4 100644
--- a/chardev/msmouse.c
+++ b/chardev/msmouse.c
@@ -171,7 +171,7 @@ static int msmouse_chr_write(struct Chardev *s, const 
uint8_t *buf, int len)
  return len;
  }
  
-static QemuInputHandler msmouse_handler = {

+static const QemuInputHandler msmouse_handler = {
  .name  = "QEMU Microsoft Mouse",
  .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
  .event = msmouse_input_event,
diff --git a/chardev/wctablet.c b/chardev/wctablet.c
index 43bdf6b608..f4008bf35b 100644
--- a/chardev/wctablet.c
+++ b/chardev/wctablet.c
@@ -178,7 +178,7 @@ static void wctablet_input_sync(DeviceState *dev)
  }
  }
  
-static QemuInputHandler wctablet_handler = {

+static const QemuInputHandler wctablet_handler = {
  .name  = "QEMU Wacom Pen Tablet",
  .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS,
  .event = wctablet_input_event,
diff --git a/hw/char/escc.c b/hw/char/escc.c
index 4be66053c1..48b30ee760 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -845,7 +845,7 @@ static void sunkbd_handle_event(DeviceState *dev, 
QemuConsole *src,
  put_queue(s, keycode);
  }
  
-static QemuInputHandler sunkbd_handler = {

+static const QemuInputHandler sunkbd_handler = {
  .name  = "sun keyboard",
  .mask  = INPUT_EVENT_MASK_KEY,
  .event = sunkbd_handle_event,
diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index 0074a9b6f8..b2130a0d70 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -321,20 +321,20 @@ static void xenfb_mouse_sync(DeviceState *dev)
  xenfb->wheel = 0;
  }
  
-static QemuInputHandler xenfb_keyboard = {

+static const QemuInputHandler xenfb_keyboard = {
  .name  = "Xen PV Keyboard",
  .mask  = INPUT_EVENT_MASK_KEY,
  .event = xenfb_key_event,
  };
  
-static QemuInputHandler xenfb_abs_mouse = {

+static const QemuInputHandler xenfb_abs_mouse = {
  .name  = "Xen PV Mouse",
  .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS,
  .event = xenfb_mouse_event,
  .sync  = xenfb_mouse_sync,
  };
  
-static QemuInputHandler xenfb_rel_mouse = {

+static const QemuInputHandler xenfb_rel_mouse = {
  .name  = "Xen PV Mouse",
  .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
  .event = xenfb_mouse_event,
diff --git a/hw/input/adb-kbd.c b/hw/input/adb-kbd.c
index a9088c910c..e21edf9acd 100644
--- a/hw/input/adb-kbd.c
+++ b/hw/input/adb-kbd.c
@@ -355,7 +355,7 @@ static void adb_kbd_reset(DeviceState *dev)
  s->count = 0;
  }
  
-static QemuInputHandler adb_keyboard_handler = {

+static const QemuInputHandler adb_keyboard_handler = {
  .name  = "QEMU ADB Keyboard",
  .mask  = INPUT_EVENT_MASK_KEY,
  .event = adb_keyboard_event,
diff --git a/hw/input/hid.c b/hw/input/hid.c
index a9c7dd1ce1..b8e85374ca 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -510,20 +510,20 @@ void hid_free(HIDState *hs)
  hid_del_idle_timer(hs);
  }
  

Re: [PATCH v2 1/3] via-ide: Fix legacy mode emulation

2023-10-17 Thread Mark Cave-Ayland

On 16/10/2023 23:16, BALATON Zoltan wrote:


On Sun, 15 Oct 2023, Mark Cave-Ayland wrote:

On 14/10/2023 17:13, BALATON Zoltan wrote:

On Sat, 14 Oct 2023, Mark Cave-Ayland wrote:

On 09/10/2023 20:54, BALATON Zoltan wrote:

The initial value for BARs were set in reset method for emulating
legacy mode at start but this does not work because PCI code resets
BARs after calling device reset method. Remove this ineffective
default to avoid confusion.

Instead move setting the BARs to a callback on writing the PCI config
regsiter that sets legacy mode (which firmwares needing this mode seem
to do) and fix their values to program it to use legacy port numbers
in this case. This does not fully emulate what the data sheet says
(which is not very clear on this) but it implements enogh to allow
both modes as used by firmwares of machines we emulate.

Signed-off-by: BALATON Zoltan 
---
  hw/ide/via.c | 41 -
  1 file changed, 36 insertions(+), 5 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index fff23803a6..43e8af8d69 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -132,11 +132,6 @@ static void via_ide_reset(DeviceState *dev)
  pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK |
   PCI_STATUS_DEVSEL_MEDIUM);
  -    pci_set_long(pci_conf + PCI_BASE_ADDRESS_0, 0x01f0);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_1, 0x03f4);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_2, 0x0170);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_3, 0x0374);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_4, 0xcc01); /* BMIBA: 20-23h 
*/
  pci_set_long(pci_conf + PCI_INTERRUPT_LINE, 0x010e);
    /* IDE chip enable, IDE configuration 1/2, IDE FIFO Configuration*/
@@ -159,6 +154,41 @@ static void via_ide_reset(DeviceState *dev)
  pci_set_long(pci_conf + 0xc0, 0x00020001);
  }
  +static void via_ide_cfg_write(PCIDevice *pd, uint32_t addr,
+  uint32_t val, int len)
+{
+    pci_default_write_config(pd, addr, val, len);
+    /*
+ * Bits 0 and 2 of the PCI programming interface register select between
+ * legacy and native mode for the two IDE channels. We don't emulate this
+ * because we cannot easily switch between ISA and PCI in QEMU so instead


As per my previous email, this statement is demonstrably false: this is now 
achievable using the portio_list*() APIs.



+ * when guest selects legacy mode we set the PCI BARs to legacy ports which
+ * works the same. We also don't care about setting each channel separately
+ * as no guest is known to do or need that. We only do this when BARs are
+ * unset when writing this register as logs from real hardware show that
+ * setting legacy mode after BARs were set it will still use ports set by
+ * BARs not ISA ports (e.g. pegasos2 Linux does this after firmware set
+ * native mode and programmed BARs and calls it non-100% native mode).
+ * But if 0x8a is written righr after reset without setting BARs then we
+ * want legacy ports (this is done by the AmigaOne firmware).
+ */
+    if (addr == PCI_CLASS_PROG && val == 0x8a &&
+    pci_get_long(pd->config + PCI_BASE_ADDRESS_0) ==
+    PCI_BASE_ADDRESS_SPACE_IO) {
+    pci_set_long(pd->config + PCI_BASE_ADDRESS_0, 0x1f0
+ | PCI_BASE_ADDRESS_SPACE_IO);
+    pci_set_long(pd->config + PCI_BASE_ADDRESS_1, 0x3f6
+ | PCI_BASE_ADDRESS_SPACE_IO);
+    pci_set_long(pd->config + PCI_BASE_ADDRESS_2, 0x170
+ | PCI_BASE_ADDRESS_SPACE_IO);
+    pci_set_long(pd->config + PCI_BASE_ADDRESS_3, 0x376
+ | PCI_BASE_ADDRESS_SPACE_IO);
+    /* BMIBA: 20-23h */
+    pci_set_long(pd->config + PCI_BASE_ADDRESS_4, 0xcc00
+ | PCI_BASE_ADDRESS_SPACE_IO);
+    }
+}


Another hint that this is not the right way to be doing this: the values you are 
placing in BARS 1 and 3 are illegal. PCI IO BARs have bit 1 forced to 0 and bit 0 
set to 1 which forces a minimum alignment of 4, so either the addresses 
0x3f6/0x376 are being rounded internally to 0x3f4/0x374 and/or you're lucky that 
this just happens to work on QEMU.


The data sheet lists these values for legacy mode bur it seems that bit 1 is 
ignored for BAR here and it ends up set to 0x3x4 with the actual reg mapped to 
0x3x7 for both values ending in 4 or 6 here and both works the same with AmigaOS 
even if I change the values here to 0x3[7f]4 so I can do that and that should then 
match the default values for these regs but not match the values listed for legacy 
mode so the data sheet is wrong either way. It still does not make sense to set 
these in reset method which will be overwritten so only works if I set them here.


Using the portio_list*() APIs really is the right way to implement this to avoid 
being affected by such issues.


Can you provide an alternative patch using portio_list? I don't know how 

Re: [PULL 19/25] gdbstub: Replace gdb_regs with an array

2023-10-17 Thread Akihiko Odaki

On 2023/10/17 23:05, Fabiano Rosas wrote:

Alex Bennée  writes:


From: Akihiko Odaki 

An array is a more appropriate data structure than a list for gdb_regs
since it is initialized only with append operation and read-only after
initialization.

Signed-off-by: Akihiko Odaki 
Reviewed-by: Alistair Francis 
Message-Id: <20230912224107.29669-13-akihiko.od...@daynix.com>
[AJB: fixed a checkpatch violation]
Signed-off-by: Alex Bennée 
Message-Id: <20231009164104.369749-20-alex.ben...@linaro.org>

diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 7b8347ed5a..3968369554 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -502,7 +502,7 @@ struct CPUState {
  
  CPUJumpCache *tb_jmp_cache;
  
-struct GDBRegisterState *gdb_regs;

+GArray *gdb_regs;
  int gdb_num_regs;
  int gdb_num_g_regs;
  QTAILQ_ENTRY(CPUState) node;
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 62608a5389..b1532118d1 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -51,7 +51,6 @@ typedef struct GDBRegisterState {
  gdb_get_reg_cb get_reg;
  gdb_set_reg_cb set_reg;
  const char *xml;
-struct GDBRegisterState *next;
  } GDBRegisterState;
  
  GDBState gdbserver_state;

@@ -386,7 +385,8 @@ static const char *get_feature_xml(const char *p, const 
char **newp,
  xml,
  g_markup_printf_escaped("",
  cc->gdb_core_xml_file));
-for (r = cpu->gdb_regs; r; r = r->next) {
+for (guint i = 0; i < cpu->gdb_regs->len; i++) {


It seems we can reach here before having initialized gdb_regs at
gdb_register_coprocessor():

Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
0x55e5310b in get_feature_xml (p=0x56a99118
 "target.xml:0,ffb", newp=0x7fffc6b0,
process=0x57a21dd0) at ../gdbstub/gdbstub.c:388

(gdb) p/x cpu->gdb_regs
$1 = 0x0


Using:
qemu-system-x86 ... -s -s

just connect GDB and it crashes.


Hi,

Sorry for trouble and thank you for reporting.

I have just posted a fix "[PATCH v4 1/5] gdbstub: Check if gdb_regs is 
NULL" as part of series "[PATCH v4 0/5] gdbstub and TCG plugin 
improvements". Please test it if possible.


Alex, you may pick the patch early since the bug is quite a serious. 
Please add "Reported-by: Fabiano Rosas " when you do so 
since I forgot it. You may skip applying target/riscv patches though 
since the maintainers may still have something to comment.


Regards,
Akihiko Odaki



[PATCH v4 3/3] tests/qtest: Introduce tests for AMD/Xilinx Versal TRNG device

2023-10-17 Thread Tong Ho
Signed-off-by: Tong Ho 
---
 tests/qtest/meson.build |   2 +-
 tests/qtest/xlnx-versal-trng-test.c | 486 
 2 files changed, 487 insertions(+), 1 deletion(-)
 create mode 100644 tests/qtest/xlnx-versal-trng-test.c

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 66795cfcd2..593ca6714b 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -216,7 +216,7 @@ qtests_aarch64 = \
   (config_all.has_key('CONFIG_TCG') and 
config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ?\
 ['tpm-tis-device-test', 'tpm-tis-device-swtpm-test'] : []) +   
  \
   (config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ? ['xlnx-can-test', 
'fuzz-xlnx-dp-test'] : []) + \
-  (config_all_devices.has_key('CONFIG_XLNX_VERSAL') ? ['xlnx-canfd-test'] : 
[]) + \
+  (config_all_devices.has_key('CONFIG_XLNX_VERSAL') ? ['xlnx-canfd-test', 
'xlnx-versal-trng-test'] : []) + \
   (config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) +  \
   (config_all.has_key('CONFIG_TCG') and
\
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : 
[]) + \
diff --git a/tests/qtest/xlnx-versal-trng-test.c 
b/tests/qtest/xlnx-versal-trng-test.c
new file mode 100644
index 00..dc19c1e83b
--- /dev/null
+++ b/tests/qtest/xlnx-versal-trng-test.c
@@ -0,0 +1,486 @@
+/*
+ * QTests for the Xilinx Versal True Random Number Generator device
+ *
+ * Copyright (c) 2023 Advanced Micro Devices, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest-single.h"
+
+/* Base Address */
+#define TRNG_BASEADDR  (0xf123)
+
+/* TRNG_INT_CTRL */
+#define R_TRNG_INT_CTRL (0x)
+#define   TRNG_INT_CTRL_CERTF_RST_MASK  (1 << 5)
+#define   TRNG_INT_CTRL_DTF_RST_MASK(1 << 4)
+#define   TRNG_INT_CTRL_DONE_RST_MASK   (1 << 3)
+#define   TRNG_INT_CTRL_CERTF_EN_MASK   (1 << 2)
+#define   TRNG_INT_CTRL_DTF_EN_MASK (1 << 1)
+#define   TRNG_INT_CTRL_DONE_EN_MASK(1)
+
+/* TRNG_STATUS */
+#define R_TRNG_STATUS  (0x0004)
+#define   TRNG_STATUS_QCNT_SHIFT   (9)
+#define   TRNG_STATUS_QCNT_MASK(7 << TRNG_STATUS_QCNT_SHIFT)
+#define   TRNG_STATUS_CERTF_MASK   (1 << 3)
+#define   TRNG_STATUS_DTF_MASK (1 << 1)
+#define   TRNG_STATUS_DONE_MASK(1)
+
+/* TRNG_CTRL */
+#define R_TRNG_CTRL(0x0008)
+#define   TRNG_CTRL_PERSODISABLE_MASK   (1 << 10)
+#define   TRNG_CTRL_SINGLEGENMODE_MASK  (1 << 9)
+#define   TRNG_CTRL_PRNGMODE_MASK   (1 << 7)
+#define   TRNG_CTRL_TSTMODE_MASK(1 << 6)
+#define   TRNG_CTRL_PRNGSTART_MASK  (1 << 5)
+#define   TRNG_CTRL_PRNGXS_MASK (1 << 3)
+#define   TRNG_CTRL_TRSSEN_MASK (1 << 2)
+#define   TRNG_CTRL_QERTUEN_MASK(1 << 1)
+#define   TRNG_CTRL_PRNGSRST_MASK   (1)
+
+/* TRNG_EXT_SEED_0 ... _11 */
+#define R_TRNG_EXT_SEED_0  (0x0040)
+#define R_TRNG_EXT_SEED_11 (R_TRNG_EXT_SEED_0 + 4 * 11)
+
+/* TRNG_PER_STRNG_0 ... 11 */
+#define R_TRNG_PER_STRNG_0 (0x0080)
+#define R_TRNG_PER_STRNG_11(R_TRNG_PER_STRNG_0 + 4 * 11)
+
+/* TRNG_CORE_OUTPUT */
+#define R_TRNG_CORE_OUTPUT (0x00c0)
+
+/* TRNG_RESET */
+#define R_TRNG_RESET   (0x00d0)
+#define   TRNG_RESET_VAL_MASK  (1)
+
+/* TRNG_OSC_EN */
+#define R_TRNG_OSC_EN  (0x00d4)
+#define   TRNG_OSC_EN_VAL_MASK (1)
+
+/* TRNG_TRNG_ISR, _IMR, _IER, _IDR */
+#define R_TRNG_ISR (0x00e0)
+#define R_TRNG_IMR (0x00e4)
+#define R_TRNG_IER (0x00e8)
+#define R_TRNG_IDR (0x00ec)
+#define   TRNG_IRQ_SLVERR_MASK (1 << 1)
+#define   TRNG_IRQ_CORE_INT_MASK   (1)
+
+#define FAILED(FMT, ...) g_error("%s(): " FMT, __func__, ## __VA_ARGS__)
+
+static const uint32_t prng_seed[12] = {
+0x01234567, 0x12345678, 0x23456789, 0x3456789a, 0x456789ab, 0x56789abc,
+0x76543210, 0x87654321, 0x98765432, 0xa9876543, 0xba987654, 0xfedcba98,
+};
+
+static const uint32_t pers_str[12] = {
+0x76543210, 0x87654321, 0x98765432, 0xa9876543, 0xba987654, 0xfedcba98,
+0x01234567, 0x12345678, 0x23456789, 0x3456789a, 0x456789ab, 0x56789abc,
+};
+
+static void trng_test_start(void)
+{
+qtest_start("-machine xlnx-versal-virt");
+}
+
+static void trng_test_stop(void)
+{
+qtest_end();
+}
+
+static void trng_test_set_uint_prop(const char *name, uint64_t value)
+{
+const char *path = "/machine/xlnx-versal/trng";
+QDict *response;
+
+response = qmp("{ 'execute': 'qom-set',"
+" 'arguments': {"
+   " 'path': %s,"
+   " 'property': %s,"
+   " 'value': %llu"
+  "} }", path,
+   name, (unsigned long long)value);
+g_assert(qdict_haskey(response, "return"));
+qobject_unref(response);
+}
+
+static void trng_write(unsigned 

[PATCH v4 0/3] AMD/Xilinx Versal TRNG support

2023-10-17 Thread Tong Ho
This series adds support for the True Random Number Generator
(TRNG) in the AMD/Xilinx Versal family of devices.

The series starts by introducing a non-cryptographic grade model
of the TRNG controller in the Versal family of devices, followed
by instantiating the model in Xilinx Versal machine.

The series ends with a q-test for sanity check of the TRNG model
in the Xilinx Versal machine.

V3 => V4
1) Patch #1
   a) Simplify the data given to g_rand_set_seed_array() as an
  array of guint32.
   b) Use qemu_guest_getrandom_nofail() as the entropy source
  when the device is configured in TRNG (mode 3).
   c) Allow 0 and (2^32-1) as valid output of the generator
   d) Add output-related context to VMSTATE.
2) Patch #3
   Remove test's assumption of PRNG output != TRNG output.

V2 => V3
1) Patch #1 Use DEFINE_PROP to define a property with custom action on set
2) Patch #1 Remove duplicated version-check on writing to CTRL4 register
3) Patch #2 Defer adding TRNG to machine's device-tree to a future patch
4) Patch #3 Code style fix: group all local vars definitions together

V1 => V2
1) Change patch #1 only
2) Use g_rand_*() PRNG from glib to replace V1's custom PRNG.
3) Implement ResettableClass for device-reset.
4) Add device-mode description to commit-message.

Best regards,
Tong Ho

Tong Ho (3):
  hw/misc: Introduce AMD/Xilix Versal TRNG device
  hw/arm: xlnx-versal-virt: Add AMD/Xilinx TRNG device
  tests/qtest: Introduce tests for AMD/Xilinx Versal TRNG device

 hw/arm/Kconfig  |   1 +
 hw/arm/xlnx-versal.c|  16 +
 hw/misc/Kconfig |   3 +
 hw/misc/meson.build |   3 +
 hw/misc/xlnx-versal-trng.c  | 727 
 include/hw/arm/xlnx-versal.h|   5 +
 include/hw/misc/xlnx-versal-trng.h  |  58 +++
 tests/qtest/meson.build |   2 +-
 tests/qtest/xlnx-versal-trng-test.c | 486 +++
 9 files changed, 1300 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/xlnx-versal-trng.c
 create mode 100644 include/hw/misc/xlnx-versal-trng.h
 create mode 100644 tests/qtest/xlnx-versal-trng-test.c

-- 
2.25.1




[PATCH v4 1/3] hw/misc: Introduce AMD/Xilix Versal TRNG device

2023-10-17 Thread Tong Ho
This adds a non-cryptographic grade implementation of the
model for the True Random Number Generator (TRNG) component
in AMD/Xilinx Versal device family.

This implements all 3 modes defined by the actual hardware
specs, all of which selectable by guest software at will
at anytime:
1) PRNG mode, in which the generated sequence is required to
   be reproducible after reseeded by the same 384-bit value
   as supplied by guest software.
2) Test mode, in which the generated sequence is required to
   be reproducible ater reseeded by the same 128-bit test
   seed supplied by guest software.
3) TRNG mode, in which non-reproducible sequence is generated
   based on periodic reseed by a suitable entropy source.

This model is only intended for non-real world testing of
guest software, where cryptographically strong PRNG or TRNG
is not needed.

This model supports versions 1 & 2 of the device, with
default to be version 2; the 'hw-version' uint32 property
can be set to 0x0100 to override the default.

Other implemented properties:
- 'forced-prng', uint64
  When set to non-zero, mode 3's entropy source is implemented
  as a deterministic sequence based on the given value and other
  deterministic parameters.
  This option allows the emulation to test guest software using
  mode 3 and to reproduce data-dependent defects.

- 'fips-fault-events', uint32, bit-mask
  bit 3: Triggers the SP800-90B entropy health test fault irq
  bit 1: Triggers the FIPS 140-2 continuous test fault irq

Signed-off-by: Tong Ho 
---
 hw/misc/Kconfig|   3 +
 hw/misc/meson.build|   3 +
 hw/misc/xlnx-versal-trng.c | 727 +
 include/hw/misc/xlnx-versal-trng.h |  58 +++
 4 files changed, 791 insertions(+)
 create mode 100644 hw/misc/xlnx-versal-trng.c
 create mode 100644 include/hw/misc/xlnx-versal-trng.h

diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index dba41afe67..cc8a8c1418 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -197,4 +197,7 @@ config DJMEMC
 config IOSB
 bool
 
+config XLNX_VERSAL_TRNG
+bool
+
 source macio/Kconfig
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index f60de33f9a..36c20d5637 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -104,6 +104,9 @@ system_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
   'xlnx-cfi-if.c',
   'xlnx-versal-cframe-reg.c',
 ))
+system_ss.add(when: 'CONFIG_XLNX_VERSAL_TRNG', if_true: files(
+  'xlnx-versal-trng.c',
+))
 system_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: 
files('stm32f2xx_syscfg.c'))
 system_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: 
files('stm32f4xx_syscfg.c'))
 system_ss.add(when: 'CONFIG_STM32F4XX_EXTI', if_true: 
files('stm32f4xx_exti.c'))
diff --git a/hw/misc/xlnx-versal-trng.c b/hw/misc/xlnx-versal-trng.c
new file mode 100644
index 00..fb0130a6b2
--- /dev/null
+++ b/hw/misc/xlnx-versal-trng.c
@@ -0,0 +1,727 @@
+/*
+ * Non-crypto strength model of the True Random Number Generator
+ * in the AMD/Xilinx Versal device family.
+ *
+ * Copyright (c) 2017-2020 Xilinx Inc.
+ * Copyright (c) 2023 Advanced Micro Devices, Inc.
+ *
+ * Written by Edgar E. Iglesias 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "hw/misc/xlnx-versal-trng.h"
+
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "qemu/guest-random.h"
+#include "qemu/timer.h"
+#include "qapi/visitor.h"
+#include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
+
+#ifndef XLNX_VERSAL_TRNG_ERR_DEBUG
+#define XLNX_VERSAL_TRNG_ERR_DEBUG 0
+#endif
+
+REG32(INT_CTRL, 0x0)
+FIELD(INT_CTRL, CERTF_RST, 5, 1)
+FIELD(INT_CTRL, DTF_RST, 4, 1)
+FIELD(INT_CTRL, DONE_RST, 3, 1)
+FIELD(INT_CTRL, CERTF_EN, 2, 1)
+FIELD(INT_CTRL, DTF_EN, 1, 1)
+FIELD(INT_CTRL, DONE_EN, 0, 1)
+REG32(STATUS, 0x4)
+FIELD(STATUS, QCNT, 9, 3)
+FIELD(STATUS, EAT, 4, 5)
+FIELD(STATUS, 

[PATCH v4 2/3] hw/arm: xlnx-versal-virt: Add AMD/Xilinx TRNG device

2023-10-17 Thread Tong Ho
Connect the support for Versal True Random Number Generator
(TRNG) device.

Warning: unlike the TRNG component in a real device from the
Versal device familiy, the connected TRNG model is not of
cryptographic grade and is not intended for use cases when
cryptograpically strong TRNG is needed.

Signed-off-by: Tong Ho 
---
 hw/arm/Kconfig   |  1 +
 hw/arm/xlnx-versal.c | 16 
 include/hw/arm/xlnx-versal.h |  5 +
 3 files changed, 22 insertions(+)

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 7e68348440..0a3ff6748d 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -482,6 +482,7 @@ config XLNX_VERSAL
 select XLNX_BBRAM
 select XLNX_EFUSE_VERSAL
 select XLNX_USB_SUBSYS
+select XLNX_VERSAL_TRNG
 
 config NPCM7XX
 bool
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index fa556d8764..4f74a64a0d 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -373,6 +373,21 @@ static void versal_create_rtc(Versal *s, qemu_irq *pic)
qdev_get_gpio_in(DEVICE(>pmc.apb_irq_orgate), 0));
 }
 
+static void versal_create_trng(Versal *s, qemu_irq *pic)
+{
+SysBusDevice *sbd;
+MemoryRegion *mr;
+
+object_initialize_child(OBJECT(s), "trng", >pmc.trng,
+TYPE_XLNX_VERSAL_TRNG);
+sbd = SYS_BUS_DEVICE(>pmc.trng);
+sysbus_realize(sbd, _fatal);
+
+mr = sysbus_mmio_get_region(sbd, 0);
+memory_region_add_subregion(>mr_ps, MM_PMC_TRNG, mr);
+sysbus_connect_irq(sbd, 0, pic[VERSAL_TRNG_IRQ]);
+}
+
 static void versal_create_xrams(Versal *s, qemu_irq *pic)
 {
 int nr_xrams = ARRAY_SIZE(s->lpd.xram.ctrl);
@@ -909,6 +924,7 @@ static void versal_realize(DeviceState *dev, Error **errp)
 versal_create_sds(s, pic);
 versal_create_pmc_apb_irq_orgate(s, pic);
 versal_create_rtc(s, pic);
+versal_create_trng(s, pic);
 versal_create_xrams(s, pic);
 versal_create_bbram(s, pic);
 versal_create_efuse(s, pic);
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
index 7b419f88c2..54f4b98d9d 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -31,6 +31,7 @@
 #include "hw/dma/xlnx_csu_dma.h"
 #include "hw/misc/xlnx-versal-crl.h"
 #include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
+#include "hw/misc/xlnx-versal-trng.h"
 #include "hw/net/xlnx-versal-canfd.h"
 #include "hw/misc/xlnx-versal-cfu.h"
 #include "hw/misc/xlnx-versal-cframe-reg.h"
@@ -116,6 +117,7 @@ struct Versal {
 } iou;
 
 XlnxZynqMPRTC rtc;
+XlnxVersalTRng trng;
 XlnxBBRam bbram;
 XlnxEFuse efuse;
 XlnxVersalEFuseCtrl efuse_ctrl;
@@ -160,6 +162,7 @@ struct Versal {
 #define VERSAL_OSPI_IRQ124
 #define VERSAL_SD0_IRQ_0   126
 #define VERSAL_EFUSE_IRQ   139
+#define VERSAL_TRNG_IRQ141
 #define VERSAL_RTC_ALARM_IRQ   142
 #define VERSAL_RTC_SECONDS_IRQ 143
 
@@ -329,4 +332,6 @@ struct Versal {
 #define MM_PMC_CRP_SIZE 0x1
 #define MM_PMC_RTC  0xf12a
 #define MM_PMC_RTC_SIZE 0x1
+#define MM_PMC_TRNG 0xf123
+#define MM_PMC_TRNG_SIZE0x1
 #endif
-- 
2.25.1




  1   2   3   4   5   6   >