Re: [PATCH 00/10] usb cleanups: remove usb_bus_find(), extract sysbus-ohci to a separate file

2024-02-25 Thread Philippe Mathieu-Daudé

On 23/2/24 13:43, Paolo Bonzini wrote:


Paolo Bonzini (10):
   acpi, qom: move object_resolve_type_unambiguous to core QOM
   ppc: sam460ex: do not use usb_bus_find()
   sh4: r2d: do not use usb_bus_find()
   mips/loongson3_virt: do not require CONFIG_USB
   hppa: do not require CONFIG_USB
   mac_newworld: do not require CONFIG_USB
   pseries: do not require CONFIG_USB
   usb: remove usb_bus_find
   usb: extract sysbus-ohci to a separate file
   usb: remove duplicate file in system_ss


Thanks, queued addressing Thomas & Markus comments.



Re: [PATCH 5/6] tests/qtest: Reorganize common code in ivshmem-test

2024-02-25 Thread Thomas Huth

On 22/02/2024 23.22, Gustavo Romero wrote:

This commit reorganizes the ivshmem-test qtest by moving common structs,
functions, and code that can be utilized by other ivshmem qtests into
two new files: ivshmem-utils.h and ivshmem-utils.c.

Enum Reg, struct ServerThread, and mktempshm() have been relocated to
these new files. Two new functions have been introduced to handle the
ivshmem server start/stop: test_ivshmem_server_{start,stop}.

To accommodate the new way for starting/stopping the ivshmem server,
struct ServerThread now includes two new members: 'server', previously
present but not a member of any struct; and 'status', a new member of a
new type, ServerStartStatus, used to track and handle service
termination properly.

Additionally, a new function, mktempsocket(), has been added to help
create a unix socket filename, similar to what mktempshm() does for the
creation of a shm file.

Finally, the ivshmem-test qtest has been adapted to use the new ivhsmem
utils. Adjustments in that sense have also been made to meson.build;
also 'rt' have been removed as a lib dependency for ivhsmem-test.c.

Two lines unrelated to these changes have had their line indentation
also fixed in meson.build.

Message-ID: <20231127052024.435743-3-gustavo.rom...@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Gustavo Romero 
---

...

diff --git a/tests/qtest/ivshmem-utils.c b/tests/qtest/ivshmem-utils.c
new file mode 100644
index 00..c2fc3463dd
--- /dev/null
+++ b/tests/qtest/ivshmem-utils.c
@@ -0,0 +1,156 @@
+/*
+ * Common utilities for testing ivshmem devices
+ *
+ * SPDX-FileCopyrightText: 2012 SUSE LINUX Products GmbH
+ * SPDX-FileCopyrightText: 2021 Red Hat, Inc.
+ * SPDX-FileCopyrightText: 2023 Linaro Ltd.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ */
+
+#include "ivshmem-utils.h"
+
+gchar *mktempshm(int size, int *fd)
+{
+while (true) {
+/* Relative path to the shm filesystem, e.g. '/dev/shm'. */
+gchar *shm_rel_path;
+
+shm_rel_path = g_strdup_printf("/ivshmem_qtest-%u-%u", getpid(),
+   g_test_rand_int());
+*fd = shm_open(shm_rel_path, O_CREAT | O_RDWR | O_EXCL,
+   S_IRWXU | S_IRWXG | S_IRWXO);
+if (*fd > 0) {
+g_assert(ftruncate(*fd, size) == 0);
+return shm_rel_path;
+}
+
+g_free(shm_rel_path);
+
+if (errno != EEXIST) {
+perror("shm_open");
+return NULL;
+}
+}
+}
+
+gchar *mktempsocket(void)
+{
+gchar *server_socket_path;
+
+server_socket_path = g_strdup_printf("%s/ivshmem_socket_qtest-%u-%u",
+ g_get_tmp_dir(), getpid(),
+ g_test_rand_int());
+return server_socket_path;
+}


You could simplify that to:

return g_strdup_printf("%s/ivshmem_socket_qtest-%u-%u",
   g_get_tmp_dir(), getpid(),
   g_test_rand_int());

Anyway:
Acked-by: Thomas Huth 




Re: [PATCH v4 21/34] migration/multifd: Add incoming QIOChannelFile support

2024-02-25 Thread Peter Xu
On Mon, Feb 26, 2024 at 03:34:26PM +0800, Peter Xu wrote:
> On Tue, Feb 20, 2024 at 07:41:25PM -0300, Fabiano Rosas wrote:
> > On the receiving side we don't need to differentiate between main
> > channel and threads, so whichever channel is defined first gets to be
> > the main one. And since there are no packets, use the atomic channel
> > count to index into the params array.
> > 
> > Signed-off-by: Fabiano Rosas 
> > ---
> >  migration/file.c  | 34 ++
> >  migration/migration.c |  3 ++-
> >  migration/multifd.c   |  3 +--
> >  3 files changed, 29 insertions(+), 11 deletions(-)
> > 
> > diff --git a/migration/file.c b/migration/file.c
> > index ac9f6ae40a..a186dc592a 100644
> > --- a/migration/file.c
> > +++ b/migration/file.c
> > @@ -8,6 +8,7 @@
> >  #include "qemu/osdep.h"
> >  #include "exec/ramblock.h"
> >  #include "qemu/cutils.h"
> > +#include "qemu/error-report.h"
> >  #include "qapi/error.h"
> >  #include "channel.h"
> >  #include "file.h"
> > @@ -15,6 +16,7 @@
> >  #include "multifd.h"
> >  #include "io/channel-file.h"
> >  #include "io/channel-util.h"
> > +#include "options.h"
> >  #include "trace.h"
> >  
> >  #define OFFSET_OPTION ",offset="
> > @@ -111,7 +113,8 @@ void file_start_incoming_migration(FileMigrationArgs 
> > *file_args, Error **errp)
> >  g_autofree char *filename = g_strdup(file_args->filename);
> >  QIOChannelFile *fioc = NULL;
> >  uint64_t offset = file_args->offset;
> > -QIOChannel *ioc;
> > +int channels = 1;
> > +int i = 0, fd;
> >  
> >  trace_migration_file_incoming(filename);
> >  
> > @@ -120,13 +123,28 @@ void file_start_incoming_migration(FileMigrationArgs 
> > *file_args, Error **errp)
> >  return;
> >  }
> >  
> > -ioc = QIO_CHANNEL(fioc);
> > -if (offset && qio_channel_io_seek(ioc, offset, SEEK_SET, errp) < 0) {
> > +if (offset &&
> > +qio_channel_io_seek(QIO_CHANNEL(fioc), offset, SEEK_SET, errp) < 
> > 0) {
> >  return;
> >  }
> > -qio_channel_set_name(QIO_CHANNEL(ioc), "migration-file-incoming");
> > -qio_channel_add_watch_full(ioc, G_IO_IN,
> > -   file_accept_incoming_migration,
> > -   NULL, NULL,
> > -   g_main_context_get_thread_default());
> > +
> > +if (migrate_multifd()) {
> > +channels += migrate_multifd_channels();
> > +}
> > +
> > +fd = fioc->fd;
> > +
> > +do {
> > +QIOChannel *ioc = QIO_CHANNEL(fioc);
> > +
> > +qio_channel_set_name(ioc, "migration-file-incoming");
> > +qio_channel_add_watch_full(ioc, G_IO_IN,
> > +   file_accept_incoming_migration,
> > +   NULL, NULL,
> > +   g_main_context_get_thread_default());
> > +} while (++i < channels && (fioc = qio_channel_file_new_fd(fd)));
> 
> Note that reusing fd here has similar risk in the future that one iochannel
> can affect the other, as potentially all shares the same fd underneath; I
> think it's the same as "two qemufile v.s. one iochannel" issue that we're
> fighting recently.
> 
> IIUC the clean case is still that we open one fd for each iochannel.  Or
> e.g. as long as one iochannel close() its fd, it immediately invalidates
> all the rest iochannels on something like use-after-free of that fd index;
> any fd operates races with another fd being opened concurrently.
> 
> Maybe we can already use a loop of qio_channel_file_new_path()?  OS should
> already cached the dentry etc. so I assume the following ones should be
> super fast?  Or there's other complexities that I didn't aware?

Or simply use dup()?

> 
> > +
> > +if (!fioc) {
> > +error_setg(errp, "Error creating migration incoming channel");
> > +}
> >  }
> > diff --git a/migration/migration.c b/migration/migration.c
> > index 16da269847..e2218b9de7 100644
> > --- a/migration/migration.c
> > +++ b/migration/migration.c
> > @@ -896,7 +896,8 @@ void migration_ioc_process_incoming(QIOChannel *ioc, 
> > Error **errp)
> >  uint32_t channel_magic = 0;
> >  int ret = 0;
> >  
> > -if (migrate_multifd() && !migrate_postcopy_ram() &&
> > +if (migrate_multifd() && !migrate_fixed_ram() &&
> > +!migrate_postcopy_ram() &&
> >  qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) {
> >  /*
> >   * With multiple channels, it is possible that we receive channels
> > diff --git a/migration/multifd.c b/migration/multifd.c
> > index 507b497d52..cb5f4fb3e0 100644
> > --- a/migration/multifd.c
> > +++ b/migration/multifd.c
> > @@ -1520,8 +1520,7 @@ void multifd_recv_new_channel(QIOChannel *ioc, Error 
> > **errp)
> >  }
> >  trace_multifd_recv_new_channel(id);
> >  } else {
> > -/* next patch gives this a meaningful value */
> > -id = 0;
> > +id = qatomic_read(_recv_state->count);
> >  }
> 

Re: [PATCH v2 3/7] target/i386: introduce function to query MMU indices

2024-02-25 Thread Zhao Liu
On Fri, Feb 23, 2024 at 02:09:44PM +0100, Paolo Bonzini wrote:
> Date: Fri, 23 Feb 2024 14:09:44 +0100
> From: Paolo Bonzini 
> Subject: [PATCH v2 3/7] target/i386: introduce function to query MMU indices
> X-Mailer: git-send-email 2.43.0
> 
> Remove knowledge of specific MMU indexes (other than MMU_NESTED_IDX and
> MMU_PHYS_IDX) from mmu_translate().  This will make it possible to split
> 32-bit and 64-bit MMU indexes.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  target/i386/cpu.h| 10 ++
>  target/i386/tcg/sysemu/excp_helper.c |  4 ++--
>  2 files changed, 12 insertions(+), 2 deletions(-)

Reviewed-by: Zhao Liu 

> 
> diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> index dfe43b82042..8c271ca62e5 100644
> --- a/target/i386/cpu.h
> +++ b/target/i386/cpu.h
> @@ -2305,6 +2305,16 @@ uint64_t cpu_get_tsc(CPUX86State *env);
>  #define MMU_NESTED_IDX  3
>  #define MMU_PHYS_IDX4
>  
> +static inline bool is_mmu_index_smap(int mmu_index)
> +{
> +return mmu_index == MMU_KSMAP_IDX;
> +}
> +
> +static inline bool is_mmu_index_user(int mmu_index)
> +{
> +return mmu_index == MMU_USER_IDX;
> +}
> +
>  static inline int cpu_mmu_index_kernel(CPUX86State *env)
>  {
>  return !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP_IDX :
> diff --git a/target/i386/tcg/sysemu/excp_helper.c 
> b/target/i386/tcg/sysemu/excp_helper.c
> index 11126c860d4..a0d5ce39300 100644
> --- a/target/i386/tcg/sysemu/excp_helper.c
> +++ b/target/i386/tcg/sysemu/excp_helper.c
> @@ -137,7 +137,7 @@ static bool mmu_translate(CPUX86State *env, const 
> TranslateParams *in,
>  const int32_t a20_mask = x86_get_a20_mask(env);
>  const target_ulong addr = in->addr;
>  const int pg_mode = in->pg_mode;
> -const bool is_user = (in->mmu_idx == MMU_USER_IDX);
> +const bool is_user = is_mmu_index_user(in->mmu_idx);
>  const MMUAccessType access_type = in->access_type;
>  uint64_t ptep, pte, rsvd_mask;
>  PTETranslate pte_trans = {
> @@ -363,7 +363,7 @@ do_check_protect_pse36:
>  }
>  
>  int prot = 0;
> -if (in->mmu_idx != MMU_KSMAP_IDX || !(ptep & PG_USER_MASK)) {
> +if (!is_mmu_index_smap(in->mmu_idx) || !(ptep & PG_USER_MASK)) {
>  prot |= PAGE_READ;
>  if ((ptep & PG_RW_MASK) || !(is_user || (pg_mode & PG_MODE_WP))) {
>  prot |= PAGE_WRITE;
> -- 
> 2.43.0
> 
> 



Re: [PATCH v2 1/7] target/i386: mask high bits of CR3 in 32-bit mode

2024-02-25 Thread Zhao Liu
On Fri, Feb 23, 2024 at 02:09:42PM +0100, Paolo Bonzini wrote:
> Date: Fri, 23 Feb 2024 14:09:42 +0100
> From: Paolo Bonzini 
> Subject: [PATCH v2 1/7] target/i386: mask high bits of CR3 in 32-bit mode
> X-Mailer: git-send-email 2.43.0
> 
> CR3 bits 63:32 are ignored in 32-bit mode (either legacy 2-level
> paging or PAE paging).  Do this in mmu_translate() to remove
> the last case where get_physical_address() meaningfully drops
> the high bits of the address.
> 
> Suggested-by: Richard Henderson 
> Fixes: 4a1e9d4d11c ("target/i386: Use atomic operations for pte updates", 
> 2022-10-18)
> Signed-off-by: Paolo Bonzini 
> ---
>  target/i386/tcg/sysemu/excp_helper.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Zhao Liu 

> 
> diff --git a/target/i386/tcg/sysemu/excp_helper.c 
> b/target/i386/tcg/sysemu/excp_helper.c
> index 5b86f439add..11126c860d4 100644
> --- a/target/i386/tcg/sysemu/excp_helper.c
> +++ b/target/i386/tcg/sysemu/excp_helper.c
> @@ -238,7 +238,7 @@ static bool mmu_translate(CPUX86State *env, const 
> TranslateParams *in,
>  /*
>   * Page table level 3
>   */
> -pte_addr = ((in->cr3 & ~0x1f) + ((addr >> 27) & 0x18)) & 
> a20_mask;
> +pte_addr = ((in->cr3 & 0xffe0ULL) + ((addr >> 27) & 0x18)) & 
> a20_mask;
>  if (!ptw_translate(_trans, pte_addr)) {
>  return false;
>  }
> @@ -306,7 +306,7 @@ static bool mmu_translate(CPUX86State *env, const 
> TranslateParams *in,
>  /*
>   * Page table level 2
>   */
> -pte_addr = ((in->cr3 & ~0xfff) + ((addr >> 20) & 0xffc)) & a20_mask;
> +pte_addr = ((in->cr3 & 0xf000ULL) + ((addr >> 20) & 0xffc)) & 
> a20_mask;
>  if (!ptw_translate(_trans, pte_addr)) {
>  return false;
>  }
> -- 
> 2.43.0
> 
> 



Re: [PATCH v4 22/34] migration/multifd: Prepare multifd sync for fixed-ram migration

2024-02-25 Thread Peter Xu
On Tue, Feb 20, 2024 at 07:41:26PM -0300, Fabiano Rosas wrote:
> The fixed-ram migration can be performed live or non-live, but it is
> always asynchronous, i.e. the source machine and the destination
> machine are not migrating at the same time. We only need some pieces
> of the multifd sync operations.
> 
> multifd_send_sync_main()
> 
>   Issued by the ram migration code on the migration thread, causes the
>   multifd send channels to synchronize with the migration thread and
>   makes the sending side emit a packet with the MULTIFD_FLUSH flag.
> 
>   With fixed-ram we want to maintain the sync on the sending side
>   because that provides ordering between the rounds of dirty pages when
>   migrating live.
> 
> MULTIFD_FLUSH
> -
>   On the receiving side, the presence of the MULTIFD_FLUSH flag on a
>   packet causes the receiving channels to start synchronizing with the
>   main thread.
> 
>   We're not using packets with fixed-ram, so there's no MULTIFD_FLUSH
>   flag and therefore no channel sync on the receiving side.
> 
> multifd_recv_sync_main()
> 
>   Issued by the migration thread when the ram migration flag
>   RAM_SAVE_FLAG_MULTIFD_FLUSH is received, causes the migration thread
>   on the receiving side to start synchronizing with the recv
>   channels. Due to compatibility, this is also issued when
>   RAM_SAVE_FLAG_EOS is received.
> 
>   For fixed-ram we only need to synchronize the channels at the end of
>   migration to avoid doing cleanup before the channels have finished
>   their IO.
> 
> Make sure the multifd syncs are only issued at the appropriate
> times. Note that due to pre-existing backward compatibility issues, we
> have the multifd_flush_after_each_section property that enables an
> older behavior of synchronizing channels more frequently (and
> inefficiently). Fixed-ram should always run with that property
> disabled (default).

What if the user enables multifd_flush_after_each_section=true?

IMHO we don't necessarily need to attach the fixed-ram loading flush to any
flag in the stream.  For fixed-ram IIUC all the loads will happen in one
shot of ram_load() anyway when parsing the ramblock list, so.. how about we
decouple the fixed-ram load flush from the stream by always do a sync in
ram_load() unconditionally?

@@ -4368,6 +4367,15 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 ret = ram_load_precopy(f);
 }
 }
+
+/*
+ * Fixed-ram migration may queue load tasks to multifd threads; make
+ * sure they're all done.
+ */
+if (migrate_fixed_ram() && migrate_multifd()) {
+multifd_recv_sync_main();
+}
+
 trace_ram_load_complete(ret, seq_iter);
 
 return ret;

Then ram_load() always guarantees synchronous loading of pages, and
fixed-ram will completely ignore multifd flushes (then we also skip it for
the ram_save_complete() like what this patch does for the rest).

> 
> Signed-off-by: Fabiano Rosas 
> ---
>  migration/ram.c | 19 ---
>  1 file changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/migration/ram.c b/migration/ram.c
> index 5932e1b8e1..c7050f6f68 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -1369,8 +1369,11 @@ static int find_dirty_block(RAMState *rs, 
> PageSearchStatus *pss)
>  if (ret < 0) {
>  return ret;
>  }
> -qemu_put_be64(f, RAM_SAVE_FLAG_MULTIFD_FLUSH);
> -qemu_fflush(f);
> +
> +if (!migrate_fixed_ram()) {
> +qemu_put_be64(f, RAM_SAVE_FLAG_MULTIFD_FLUSH);
> +qemu_fflush(f);
> +}
>  }
>  /*
>   * If memory migration starts over, we will meet a dirtied page
> @@ -3112,7 +3115,8 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
>  return ret;
>  }
>  
> -if (migrate_multifd() && !migrate_multifd_flush_after_each_section()) {
> +if (migrate_multifd() && !migrate_multifd_flush_after_each_section()
> +&& !migrate_fixed_ram()) {
>  qemu_put_be64(f, RAM_SAVE_FLAG_MULTIFD_FLUSH);
>  }
>  
> @@ -4253,6 +4257,15 @@ static int ram_load_precopy(QEMUFile *f)
>  break;
>  case RAM_SAVE_FLAG_EOS:
>  /* normal exit */
> +if (migrate_fixed_ram()) {
> +/*
> + * The EOS flag appears multiple times on the
> + * stream. Fixed-ram needs only one sync at the
> + * end. It will be done on the flush flag above.
> + */
> +break;
> +}
> +
>  if (migrate_multifd() &&
>  migrate_multifd_flush_after_each_section()) {
>  multifd_recv_sync_main();
> -- 
> 2.35.3
> 

-- 
Peter Xu




Re: [PATCH] migration: Free argv

2024-02-25 Thread Akihiko Odaki

On 2024/02/26 12:49, Peter Xu wrote:

On Sun, Feb 25, 2024 at 02:54:01PM +0900, Akihiko Odaki wrote:

exec_start_outgoing_migration() and exec_start_incoming_migration()
leak argv because it uses g_steal_pointer() is used to pass argv
qio_channel_command_new_spawn() while it does not free argv either.

Removing g_steal_pointer() is not sufficient though because argv is
typed g_auto(GStrv), which means the array of strings *and strings* will
be freed. The strings are only borrowed from the caller of
exec_start_outgoing_migration() and exec_start_incoming_migration() so
freeing them result in double-free.

Instead, type argv as g_autofree char **. This ensures only the array
of strings will be freed and the strings won't be freed. Also, remove
unnecessary casts according to the new type.

Fixes: cbab4face57b ("migration: convert exec backend to accept 
MigrateAddress.")
Signed-off-by: Akihiko Odaki 


Cc: qemu-stable 
Reviewed-by: Peter Xu 

This should conflict with Steve's other series:

https://lore.kernel.org/r/1708638470-114846-1-git-send-email-steven.sist...@oracle.com

Considering this can be stable material, should be easier if we have the
other series rebased on top of this, even if that was sent first..

Steve, do you still plan to repost your series?  Maybe you can review it &
pick this up into your series?  Then whoever pick up your series will pick
up both (Markus will?)?


Patch "migration: simplify exec migration functions" included in the 
series fixes the identical problem:

https://lore.kernel.org/all/1708638470-114846-6-git-send-email-steven.sist...@oracle.com/

I withdraw my patch as duplicate.

Regards,
Akihiko Odaki



Re: [RFC PATCH] target/ppc/mmu: Silent maybe-uninitialized error in ppc_hash64_xlate()

2024-02-25 Thread Thomas Huth

On 23/02/2024 09.32, Philippe Mathieu-Daudé wrote:

Initialize apshift to avoid a maybe-uninitialized error:

   C compiler for the host machine: cc -m64 -mbig-endian (gcc 13.2.0 "cc (Debian 
13.2.0-10) 13.2.0")
   C linker for the host machine: cc -m64 -mbig-endian ld.bfd 2.41.90.20240115
   Host machine cpu family: ppc64
   Host machine cpu: ppc64
   ...
   target/ppc/mmu-hash64.c: In function 'ppc_hash64_xlate':
   target/ppc/mmu-hash64.c:1154:15: error: 'apshift' may be used uninitialized 
[-Werror=maybe-uninitialized]
1154 | *raddrp = deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, eaddr);
 |   ^
   target/ppc/mmu-hash64.c:947:14: note: 'apshift' was declared here
 947 | unsigned apshift;
 |  ^~~

The call chain is:

   ppc_hash64_xlate -> ppc_hash64_htab_lookup -> ppc_hash64_pteg_search

ppc_hash64_pteg_search() either sets *pshift or returns -1,

ppc_hash64_htab_lookup() returns if ppc_hash64_pteg_search()
returned -1:

   1068:ptex = ppc_hash64_htab_lookup(cpu, slb, eaddr, , );
   1069:if (ptex == -1) {
   1070:if (!guest_visible) {
   1071:return false;
   1072:}
...
   1087:return false;

So IIUC this "uninitialized use" can not happens.

Signed-off-by: Philippe Mathieu-Daudé 
---
I had this in an old branch (2 months old) I just rebased,
and don't get why nobody else got this error yet.


That's weird, indeed. Did you maybe compile without optimizations when you 
hit the error?


 Thomas





Re: [PATCH 02/10] ppc: sam460ex: do not use usb_bus_find()

2024-02-25 Thread Markus Armbruster
Paolo Bonzini  writes:

> usb_bus_find() is always used with argument -1; it can be replaced with
> a search of the single USB bus on the machine.
>
> Suggested-by: Philippe Mathieu-Daudé 
> Signed-off-by: Paolo Bonzini 
> ---
>  hw/ppc/sam460ex.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
> index 1e615b8d355..4d5655ab6b4 100644
> --- a/hw/ppc/sam460ex.c
> +++ b/hw/ppc/sam460ex.c
> @@ -273,6 +273,7 @@ static void sam460ex_init(MachineState *machine)
>  DeviceState *uic[4];
>  int i;
>  PCIBus *pci_bus;
> +USBBus *usb_bus;
>  PowerPCCPU *cpu;
>  CPUPPCState *env;
>  I2CBus *i2c;
> @@ -420,8 +421,9 @@ static void sam460ex_init(MachineState *machine)
>  sysbus_realize_and_unref(sbdev, _fatal);
>  sysbus_mmio_map(sbdev, 0, 0x4bffd);
>  sysbus_connect_irq(sbdev, 0, qdev_get_gpio_in(uic[2], 30));
> -usb_create_simple(usb_bus_find(-1), "usb-kbd");
> -usb_create_simple(usb_bus_find(-1), "usb-mouse");
> +usb_bus = USB_BUS(object_resolve_type_unambiguous(TYPE_USB_BUS, 
> _abort));

This long line is really easy to break.

> +usb_create_simple(usb_bus, "usb-kbd");
> +usb_create_simple(usb_bus, "usb-mouse");
>  
>  /* PCIe buses */
>  dev = qdev_new(TYPE_PPC460EX_PCIE_HOST);




Re: [PATCH 04/10] mips/loongson3_virt: do not require CONFIG_USB

2024-02-25 Thread Markus Armbruster
Paolo Bonzini  writes:

> Once the Kconfig for hw/mips is cleaned up, it will be possible to build a
> binary that does not include any USB host controller and therefore that
> does not include the code guarded by CONFIG_USB.  While the simpler
> creation functions such as usb_create_simple can be inlined, this is not
> true of usb_bus_find().  Remove it, replacing it with a search of the
> single USB bus created by loongson3_virt_devices_init().
>
> Signed-off-by: Paolo Bonzini 
> ---
>  hw/mips/loongson3_virt.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
> index caedde2df00..b2a8b22b4ea 100644
> --- a/hw/mips/loongson3_virt.c
> +++ b/hw/mips/loongson3_virt.c
> @@ -447,8 +447,9 @@ static inline void 
> loongson3_virt_devices_init(MachineState *machine,
>  
>  if (defaults_enabled() && object_class_by_name("pci-ohci")) {
>  pci_create_simple(pci_bus, -1, "pci-ohci");
> -usb_create_simple(usb_bus_find(-1), "usb-kbd");
> -usb_create_simple(usb_bus_find(-1), "usb-tablet");
> +Object *usb_bus = object_resolve_type_unambiguous(TYPE_USB_BUS, 
> _abort);
> +usb_create_simple(USB_BUS(usb_bus), "usb-kbd");
> +usb_create_simple(USB_BUS(usb_bus), "usb-tablet");

In the previous patches, you cast just once, like this:

   USBBus *usb_bus = 
USB_BUS(object_resolve_type_unambiguous(TYPE_USB_BUS, _abort));
   usb_create_simple(usb_bus, "usb-kbd");
   usb_create_simple(usb_bus, "usb-tablet");

Could you do that here, too?

Same for the next few patches.

>  }
>  
>  pci_init_nic_devices(pci_bus, mc->default_nic);




Re: [PATCH 02/10] ppc: sam460ex: do not use usb_bus_find()

2024-02-25 Thread Markus Armbruster
Please ignore this one; I replied to the wrong patch by accident.




Re: [PATCH v2 3/3] hw/ide: Include 'ide_internal.h' from current path

2024-02-25 Thread Markus Armbruster
BALATON Zoltan  writes:

> On Sun, 25 Feb 2024, Philippe Mathieu-Daudé wrote:
>> Rename "internal.h" as "ide_internal.h", and include
>
> Is there a convention about using underscore or dash in file names? The 
> headers Thomas added are using - as well as ahci-allwinner.c, only 
> ahci_internal.h has _ (but there are others elsewhere such as pci_device.h). 
> Maybe we should be consistent at least within IDE and this series is now a 
> good opportunity for renaming these headers to match. But it's just a small 
> nit, thanks for picking this up.

This is one of the many unnecessary inconsistencies we're inflicting on
ourselves.

We have more than 3600 file names containing '-', and more almost 2700
containing '_'.  Bizarrely, 68 of them contain both.

I strongly prefer '_' myself.

Zoltan is making a local consistency argument for '-'.

Let's use '-' here.




Re: [PATCH V1] migration: export fewer options

2024-02-25 Thread Markus Armbruster
Steve Sistare  writes:

> A small number of migration options are accessed by migration clients,
> but to see them clients must include all of options.h, which is mostly
> for migration core code.  migrate_mode() in particular will be needed by
> multiple clients.
>
> Refactor the option declarations so clients can see the necessary few via
> misc.h, which already exports a portion of the client API.
>
> Signed-off-by: Steve Sistare 
> ---
> I suggest that eventually we should define a single file migration/client.h
> which exports everything needed by the simpler clients: blockers, notifiers,
> options, cpr, and state accessors.
> ---
> ---
>  hw/vfio/migration.c |  1 -
>  hw/virtio/virtio-balloon.c  |  1 -
>  include/migration/misc.h|  1 +
>  include/migration/options-pub.h | 24 
>  migration/options.h |  6 +-

Unusual naming.  We have zero headers named -pub.h or -public.h, and
dozens named like -int.h or -internal.h.  Please stick to the existing
convention.

[...]




Re: [PATCH 02/10] ppc: sam460ex: do not use usb_bus_find()

2024-02-25 Thread Markus Armbruster
Paolo Bonzini  writes:

> Once the Kconfig for hw/mips is cleaned up, it will be possible to build a
> binary that does not include any USB host controller and therefore that
> does not include the code guarded by CONFIG_USB.  While the simpler
> creation functions such as usb_create_simple can be inlined, this is not
> true of usb_bus_find().  Remove it, replacing it with a search of the
> single USB bus created by loongson3_virt_devices_init().
>
> Signed-off-by: Paolo Bonzini 
> ---
>  hw/mips/loongson3_virt.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
> index caedde2df00..b2a8b22b4ea 100644
> --- a/hw/mips/loongson3_virt.c
> +++ b/hw/mips/loongson3_virt.c
> @@ -447,8 +447,9 @@ static inline void 
> loongson3_virt_devices_init(MachineState *machine,
>  
>  if (defaults_enabled() && object_class_by_name("pci-ohci")) {
>  pci_create_simple(pci_bus, -1, "pci-ohci");
> -usb_create_simple(usb_bus_find(-1), "usb-kbd");
> -usb_create_simple(usb_bus_find(-1), "usb-tablet");
> +Object *usb_bus = object_resolve_type_unambiguous(TYPE_USB_BUS, 
> _abort);
> +usb_create_simple(USB_BUS(usb_bus), "usb-kbd");
> +usb_create_simple(USB_BUS(usb_bus), "usb-tablet");

In the previous patches, you cast just once, like this:

   USBBus *usb_bus = 
USB_BUS(object_resolve_type_unambiguous(TYPE_USB_BUS, _abort));
   usb_create_simple(usb_bus, "usb-kbd");
   usb_create_simple(usb_bus, "usb-tablet");

Could you do that here, too?

Same for the next few patches.

>  }
>  
>  pci_init_nic_devices(pci_bus, mc->default_nic);




Re: [PATCH] hw/rtc/sun4v-rtc: Relicense to GPLv2-or-later

2024-02-25 Thread Markus Armbruster
Peter Maydell  writes:

> The sun4v RTC device model added under commit a0e893039cf2ce0 in 2016
> was unfortunately added with a license of GPL-v3-or-later, which is
> not compatible with other QEMU code which has a GPL-v2-only license.
>
> Relicense the code in the .c and the .h file to GPL-v2-or-later,
> to make it compatible with the rest of QEMU.
>
> Signed-off-by: Peter Maydell 
> ---
> Before we can commit this to either head-of-git or any stable branch,
> we need a Signed-off-by: from everybody who's touched this file (or,
> for corporate contributions, from somebody from the relevant company
> who can confirm that the company is OK with the licensing, which is
> RedHat and Linaro in this case).
>
> The full list of people who've made changes to the file is:
>  Artyom Tarasenko 
>  Philippe Mathieu-Daudé 
>  Markus Armbruster 
>  Eduardo Habkost 

I'm cc'ing edua...@habkost.net.

> (Artyom is the original author; everybody else's changes are largely
> mechanical, refactoring, etc.  We've done some behind-the-scenes
> coordination so I don't anticipate any problems getting the
> signoffs.)

I doubt my contributions to these files are creative enough to qualify
for copyright, but better safe than sorry:

Signed-off-by: Markus Armbruster 




RE: [PATCH rfcv2 14/18] intel_iommu: Add a framework to check and sync host IOMMU cap/ecap

2024-02-25 Thread Duan, Zhenzhong


>-Original Message-
>From: Eric Auger 
>Subject: Re: [PATCH rfcv2 14/18] intel_iommu: Add a framework to check
>and sync host IOMMU cap/ecap
>
>
>
>On 2/1/24 08:28, Zhenzhong Duan wrote:
>> From: Yi Liu 
>>
>> Add a framework to check and synchronize host IOMMU cap/ecap with
>> vIOMMU cap/ecap.
>>
>> The sequence will be:
>>
>> vtd_cap_init() initializes iommu->cap/ecap.
>> vtd_check_hdev() update iommu->cap/ecap based on host cap/ecap.
>> iommu->cap_frozen set when machine create done, iommu->cap/ecap
>become readonly.
>>
>> Implementation details for different backends will be in following patches.
>>
>> Signed-off-by: Yi Liu 
>> Signed-off-by: Yi Sun 
>> Signed-off-by: Zhenzhong Duan 
>> ---
>>  include/hw/i386/intel_iommu.h |  1 +
>>  hw/i386/intel_iommu.c | 41
>++-
>>  2 files changed, 41 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/hw/i386/intel_iommu.h
>b/include/hw/i386/intel_iommu.h
>> index bbc7b96add..c71a133820 100644
>> --- a/include/hw/i386/intel_iommu.h
>> +++ b/include/hw/i386/intel_iommu.h
>> @@ -283,6 +283,7 @@ struct IntelIOMMUState {
>>
>>  uint64_t cap;   /* The value of capability reg */
>>  uint64_t ecap;  /* The value of extended capability reg 
>> */
>> +bool cap_frozen;/* cap/ecap become read-only after 
>> frozen */
>>
>>  uint32_t context_cache_gen; /* Should be in [1,MAX] */
>>  GHashTable *iotlb;  /* IOTLB */
>> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>> index ffa1ad6429..7ed2b79669 100644
>> --- a/hw/i386/intel_iommu.c
>> +++ b/hw/i386/intel_iommu.c
>> @@ -3819,6 +3819,31 @@ VTDAddressSpace
>*vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,
>>  return vtd_dev_as;
>>  }
>>
>> +static int vtd_check_legacy_hdev(IntelIOMMUState *s,
>> + IOMMULegacyDevice *ldev,
>> + Error **errp)
>> +{
>> +return 0;
>> +}
>> +
>> +static int vtd_check_iommufd_hdev(IntelIOMMUState *s,
>> +  IOMMUFDDevice *idev,
>> +  Error **errp)
>> +{
>> +return 0;
>> +}
>> +
>> +static int vtd_check_hdev(IntelIOMMUState *s, VTDHostIOMMUDevice
>*vtd_hdev,
>> +  Error **errp)
>> +{
>> +HostIOMMUDevice *base_dev = vtd_hdev->dev;
>> +
>> +if (base_dev->type == HID_LEGACY) {
>> +return vtd_check_legacy_hdev(s, vtd_hdev->ldev, errp);
>> +}
>> +return vtd_check_iommufd_hdev(s, vtd_hdev->idev, errp);
>Couldn't we have HostIOMMUDevice ops instead of having this check here?

Hmm, not sure if this is deserved. If we define such ops, it has only one 
function
check_hdev and we still need to check base_dev->type to assign different
function to HostIOMMUDevice.ops.check_hdev in vtd_dev_set_iommu_device().

Thanks
Zhenzhong


Re: [PATCH 4/4] replay: simple auto-snapshot mode for record

2024-02-25 Thread Nicholas Piggin
On Fri Aug 18, 2023 at 2:36 PM AEST, Pavel Dovgalyuk wrote:
> On 14.08.2023 19:31, Nicholas Piggin wrote:
> > record makes an initial snapshot when the machine is created, to enable
> > reverse-debugging. Often the issue being debugged appears near the end of
> > the trace, so it is important for performance to keep snapshots close to
> > the end.
> > 
> > This implements a periodic snapshot mode that keeps a rolling set of
> > recent snapshots.
> > 
> > Arguably this should be done by the debugger or a program that talks to
> > QMP, but for setting up simple scenarios and tests, it is convenient to
> > have this feature.

I'm looking at resurrecting this to help add a bit of testing...

[snip]

> > +static void replay_snapshot_timer_cb(void *opaque)
> > +{
> > +Error *err = NULL;
> > +char *name;
> > +
> > +if (!replay_can_snapshot()) {
> > +/* Try again soon */
> > +timer_mod(replay_snapshot_timer,
> > +  qemu_clock_get_ms(QEMU_CLOCK_REALTIME) +
> > +  replay_snapshot_periodic_delay / 10);
> > +return;
> > +}
> > +
> > +name = g_strdup_printf("%s-%d", replay_snapshot, 
> > replay_snapshot_count);
> > +if (!save_snapshot(name,
> > +   true, NULL, false, NULL, )) {
> > +error_report_err(err);
> > +error_report("Could not create periodic snapshot "
> > + "for icount record, disabling");
> > +g_free(name);
> > +return;
> > +}
> > +g_free(name);
> > +replay_snapshot_count++;
> > +
> > +if (replay_snapshot_periodic_nr_keep >= 1 &&
> > +replay_snapshot_count > replay_snapshot_periodic_nr_keep) {
> > +int del_nr;
> > +
> > +del_nr = replay_snapshot_count - replay_snapshot_periodic_nr_keep 
> > - 1;
> > +name = g_strdup_printf("%s-%d", replay_snapshot, del_nr);
> > +if (!delete_snapshot(name, false, NULL, )) {
> > +error_report_err(err);
> > +error_report("Could not delete periodic snapshot "
> > + "for icount record");
> > +}
> > +g_free(name);
> > +}
> > +
> > +timer_mod(replay_snapshot_timer,
> > +  qemu_clock_get_ms(QEMU_CLOCK_REALTIME) +
> > +  replay_snapshot_periodic_delay);
>
> I'm not sure that realtime is not the best choice for such of a timer.
> Virtual machine may be stopped or slowed down for some reason.

My thinking was that, say if you snapshot every 10 seconds of real time
executed, then you should have an upper limit on the order of 10 seconds
to perform a reverse-debug operation (so long as you don't exceed your
nr_keep limit).

Is it worth worrying about complexity of slowdowns and vm pausing?
Maybe it could stop snapshotting on a host pause.

> > +}
> > +
> >   void replay_vmstate_init(void)
> >   {
> >   Error *err = NULL;
> > @@ -81,6 +128,16 @@ void replay_vmstate_init(void)
> >   error_report("Could not create snapshot for icount 
> > record");
> >   exit(1);
> >   }
> > +
> > +if (replay_snapshot_mode == REPLAY_SNAPSHOT_MODE_PERIODIC) {
> > +replay_snapshot_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
> > + 
> > replay_snapshot_timer_cb,
> > + NULL);
> > +timer_mod(replay_snapshot_timer,
> > +  qemu_clock_get_ms(QEMU_CLOCK_REALTIME) +
> > +  replay_snapshot_periodic_delay);
> > +}
> > +
>
> Please also delete placeholder comment for the snapshotting timer
> in replay_enable function.

Wil do.

> >   } else if (replay_mode == REPLAY_MODE_PLAY) {
> >   if (!load_snapshot(replay_snapshot, NULL, false, NULL, )) 
> > {
> >   error_report_err(err);
> > diff --git a/replay/replay.c b/replay/replay.c
> > index e64f71209a..fa5930700d 100644
> > --- a/replay/replay.c
> > +++ b/replay/replay.c
> > @@ -29,6 +29,10 @@
> >   ReplayMode replay_mode = REPLAY_MODE_NONE;
> >   char *replay_snapshot;
> >   
> > +ReplaySnapshotMode replay_snapshot_mode;
> > +uint64_t replay_snapshot_periodic_delay;
> > +int replay_snapshot_periodic_nr_keep;
> > +
> >   /* Name of replay file  */
> >   static char *replay_filename;
> >   ReplayState replay_state;
> > @@ -313,6 +317,27 @@ void replay_configure(QemuOpts *opts)
> >   }
> >   
> >   replay_snapshot = g_strdup(qemu_opt_get(opts, "rrsnapshot"));
> > +if (replay_snapshot && mode == REPLAY_MODE_RECORD) {
>
> Can such a snapshotting may be useful in replay mode?

Does snapshotting do anything in replay mode? I assume if we did
snapshotting based on the machine timer then we'd have to support
it here so the timer events get replayed properly, at least. But
I was trying to get by with minimum complexity :)

Thanks,
Nick



Re: [PATCH v4 21/34] migration/multifd: Add incoming QIOChannelFile support

2024-02-25 Thread Peter Xu
On Tue, Feb 20, 2024 at 07:41:25PM -0300, Fabiano Rosas wrote:
> On the receiving side we don't need to differentiate between main
> channel and threads, so whichever channel is defined first gets to be
> the main one. And since there are no packets, use the atomic channel
> count to index into the params array.
> 
> Signed-off-by: Fabiano Rosas 
> ---
>  migration/file.c  | 34 ++
>  migration/migration.c |  3 ++-
>  migration/multifd.c   |  3 +--
>  3 files changed, 29 insertions(+), 11 deletions(-)
> 
> diff --git a/migration/file.c b/migration/file.c
> index ac9f6ae40a..a186dc592a 100644
> --- a/migration/file.c
> +++ b/migration/file.c
> @@ -8,6 +8,7 @@
>  #include "qemu/osdep.h"
>  #include "exec/ramblock.h"
>  #include "qemu/cutils.h"
> +#include "qemu/error-report.h"
>  #include "qapi/error.h"
>  #include "channel.h"
>  #include "file.h"
> @@ -15,6 +16,7 @@
>  #include "multifd.h"
>  #include "io/channel-file.h"
>  #include "io/channel-util.h"
> +#include "options.h"
>  #include "trace.h"
>  
>  #define OFFSET_OPTION ",offset="
> @@ -111,7 +113,8 @@ void file_start_incoming_migration(FileMigrationArgs 
> *file_args, Error **errp)
>  g_autofree char *filename = g_strdup(file_args->filename);
>  QIOChannelFile *fioc = NULL;
>  uint64_t offset = file_args->offset;
> -QIOChannel *ioc;
> +int channels = 1;
> +int i = 0, fd;
>  
>  trace_migration_file_incoming(filename);
>  
> @@ -120,13 +123,28 @@ void file_start_incoming_migration(FileMigrationArgs 
> *file_args, Error **errp)
>  return;
>  }
>  
> -ioc = QIO_CHANNEL(fioc);
> -if (offset && qio_channel_io_seek(ioc, offset, SEEK_SET, errp) < 0) {
> +if (offset &&
> +qio_channel_io_seek(QIO_CHANNEL(fioc), offset, SEEK_SET, errp) < 0) {
>  return;
>  }
> -qio_channel_set_name(QIO_CHANNEL(ioc), "migration-file-incoming");
> -qio_channel_add_watch_full(ioc, G_IO_IN,
> -   file_accept_incoming_migration,
> -   NULL, NULL,
> -   g_main_context_get_thread_default());
> +
> +if (migrate_multifd()) {
> +channels += migrate_multifd_channels();
> +}
> +
> +fd = fioc->fd;
> +
> +do {
> +QIOChannel *ioc = QIO_CHANNEL(fioc);
> +
> +qio_channel_set_name(ioc, "migration-file-incoming");
> +qio_channel_add_watch_full(ioc, G_IO_IN,
> +   file_accept_incoming_migration,
> +   NULL, NULL,
> +   g_main_context_get_thread_default());
> +} while (++i < channels && (fioc = qio_channel_file_new_fd(fd)));

Note that reusing fd here has similar risk in the future that one iochannel
can affect the other, as potentially all shares the same fd underneath; I
think it's the same as "two qemufile v.s. one iochannel" issue that we're
fighting recently.

IIUC the clean case is still that we open one fd for each iochannel.  Or
e.g. as long as one iochannel close() its fd, it immediately invalidates
all the rest iochannels on something like use-after-free of that fd index;
any fd operates races with another fd being opened concurrently.

Maybe we can already use a loop of qio_channel_file_new_path()?  OS should
already cached the dentry etc. so I assume the following ones should be
super fast?  Or there's other complexities that I didn't aware?

> +
> +if (!fioc) {
> +error_setg(errp, "Error creating migration incoming channel");
> +}
>  }
> diff --git a/migration/migration.c b/migration/migration.c
> index 16da269847..e2218b9de7 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -896,7 +896,8 @@ void migration_ioc_process_incoming(QIOChannel *ioc, 
> Error **errp)
>  uint32_t channel_magic = 0;
>  int ret = 0;
>  
> -if (migrate_multifd() && !migrate_postcopy_ram() &&
> +if (migrate_multifd() && !migrate_fixed_ram() &&
> +!migrate_postcopy_ram() &&
>  qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) {
>  /*
>   * With multiple channels, it is possible that we receive channels
> diff --git a/migration/multifd.c b/migration/multifd.c
> index 507b497d52..cb5f4fb3e0 100644
> --- a/migration/multifd.c
> +++ b/migration/multifd.c
> @@ -1520,8 +1520,7 @@ void multifd_recv_new_channel(QIOChannel *ioc, Error 
> **errp)
>  }
>  trace_multifd_recv_new_channel(id);
>  } else {
> -/* next patch gives this a meaningful value */
> -id = 0;
> +id = qatomic_read(_recv_state->count);
>  }
>  
>  p = _recv_state->params[id];
> -- 
> 2.35.3
> 

-- 
Peter Xu




Re: [PATCH v2 20/27] plugins: create CPUPluginState and migrate plugin_mask

2024-02-25 Thread Pierrick Bouvier

On 2/23/24 8:21 PM, Alex Bennée wrote:

We are going to want to keep track of some per-vCPU data for plugins
and the logical place to do so is in track it in CPUState. For now
this just moves the plugin_mask (renamed to event_mask) as the memory
callbacks are accessed directly by TCG generated code.

Signed-off-by: Alex Bennée 
---
  include/hw/core/cpu.h   | 11 +++
  include/qemu/plugin.h   | 13 +
  include/qemu/typedefs.h |  1 +
  accel/tcg/plugin-gen.c  |  3 ++-
  hw/core/cpu-common.c|  1 +
  plugins/core.c  | 12 +---
  6 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 4b659799b00..af1a29526d4 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -31,7 +31,6 @@
  #include "qemu/rcu_queue.h"
  #include "qemu/queue.h"
  #include "qemu/thread.h"
-#include "qemu/plugin-event.h"
  #include "qom/object.h"
  
  typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,

@@ -434,7 +433,8 @@ struct qemu_work_item;
   * @kvm_fd: vCPU file descriptor for KVM.
   * @work_mutex: Lock to prevent multiple access to @work_list.
   * @work_list: List of pending asynchronous work.
- * @plugin_mask: Plugin event bitmap. Modified only via async work.
+ * @plugin_mem_cbs: active plugin memory callbacks
+ * @plugin_state: per-CPU plugin state
   * @ignore_memory_transaction_failures: Cached copy of the MachineState
   *flag of the same name: allows the board to suppress calling of the
   *CPU do_transaction_failed hook function.
@@ -526,10 +526,13 @@ struct CPUState {
  /* Use by accel-block: CPU is executing an ioctl() */
  QemuLockCnt in_ioctl_lock;
  
-DECLARE_BITMAP(plugin_mask, QEMU_PLUGIN_EV_MAX);

-
  #ifdef CONFIG_PLUGIN
+/*
+ * The callback pointer stays in the main CPUState as it is
+ * accessed via TCG (see gen_empty_mem_helper).
+ */
  GArray *plugin_mem_cbs;
+CPUPluginState *plugin_state;
  #endif
  
  /* TODO Move common fields from CPUArchState here. */

diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index b0c5ac68293..0e7b9693d80 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -186,6 +186,19 @@ struct qemu_plugin_insn *qemu_plugin_tb_insn_get(struct 
qemu_plugin_tb *tb,
  return insn;
  }
  
+/**

+ * struct CPUPluginState - per-CPU state for plugins
+ * @event_mask: plugin event bitmap. Modified only via async work.
+ */
+struct CPUPluginState {
+DECLARE_BITMAP(event_mask, QEMU_PLUGIN_EV_MAX);
+};
+
+/**
+ * qemu_plugin_create_vcpu_state: allocate plugin state
+ */
+CPUPluginState * qemu_plugin_create_vcpu_state(void);
+
  void qemu_plugin_vcpu_init_hook(CPUState *cpu);
  void qemu_plugin_vcpu_exit_hook(CPUState *cpu);
  void qemu_plugin_tb_trans_cb(CPUState *cpu, struct qemu_plugin_tb *tb);
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index d7c703b4ae9..a028dba4d0b 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -42,6 +42,7 @@ typedef struct CompatProperty CompatProperty;
  typedef struct ConfidentialGuestSupport ConfidentialGuestSupport;
  typedef struct CPUAddressSpace CPUAddressSpace;
  typedef struct CPUArchState CPUArchState;
+typedef struct CPUPluginState CPUPluginState;
  typedef struct CpuInfoFast CpuInfoFast;
  typedef struct CPUJumpCache CPUJumpCache;
  typedef struct CPUState CPUState;
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index b37ce7683e6..ac6b52b9ec9 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -43,6 +43,7 @@
   * CPU's index into a TCG temp, since the first callback did it already.
   */
  #include "qemu/osdep.h"
+#include "qemu/plugin.h"
  #include "cpu.h"
  #include "tcg/tcg.h"
  #include "tcg/tcg-temp-internal.h"
@@ -831,7 +832,7 @@ bool plugin_gen_tb_start(CPUState *cpu, const 
DisasContextBase *db,
  {
  bool ret = false;
  
-if (test_bit(QEMU_PLUGIN_EV_VCPU_TB_TRANS, cpu->plugin_mask)) {

+if (test_bit(QEMU_PLUGIN_EV_VCPU_TB_TRANS, cpu->plugin_state->event_mask)) 
{
  struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
  int i;
  
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c

index 68786360ea5..6a8c290fc75 100644
--- a/hw/core/cpu-common.c
+++ b/hw/core/cpu-common.c
@@ -224,6 +224,7 @@ static void cpu_common_realizefn(DeviceState *dev, Error 
**errp)
  
  /* Plugin initialization must wait until the cpu start executing code */

  if (tcg_enabled()) {
+cpu->plugin_state = qemu_plugin_create_vcpu_state();
  async_run_on_cpu(cpu, qemu_plugin_vcpu_init__async, RUN_ON_CPU_NULL);
  }
  
diff --git a/plugins/core.c b/plugins/core.c

index 2392bbb8889..83745663f32 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -17,6 +17,7 @@
  #include "qapi/error.h"
  #include "qemu/lockable.h"
  #include "qemu/option.h"
+#include "qemu/plugin.h"
  #include "qemu/rcu_queue.h"
  #include "qemu/xxhash.h"
  #include "qemu/rcu.h"
@@ -53,7 +54,7 @@ 

Re: [PATCH v2 24/27] contrib/plugins: extend execlog to track register changes

2024-02-25 Thread Pierrick Bouvier

On 2/23/24 8:21 PM, Alex Bennée wrote:

With the new plugin register API we can now track changes to register
values. Currently the implementation is fairly dumb which will slow
down if a large number of register values are being tracked. This
could be improved by only instrumenting instructions which mention
registers we are interested in tracking.

Example usage:

   ./qemu-aarch64 -D plugin.log -d plugin \
  -cpu max,sve256=on \
  -plugin contrib/plugins/libexeclog.so,reg=sp,reg=z\* \
  ./tests/tcg/aarch64-linux-user/sha512-sve

will display in the execlog any changes to the stack pointer (sp) and
the SVE Z registers.

As testing registers every instruction will be quite a heavy operation
there is an additional flag which attempts to optimise the register
tracking by only instrumenting instructions which are likely to change
its value. This relies on the QEMU disassembler showing up the register
names in disassembly so is an explicit opt-in.

Message-Id: <20240103173349.398526-41-alex.ben...@linaro.org>
Signed-off-by: Alex Bennée 
Cc: Akihiko Odaki 
Based-On: <20231025093128.33116-19-akihiko.od...@daynix.com>

---
v3
   - just use a GArray for the CPU array
   - drop duplicate of cpu_index
v4
   - rebase and api fixups
   - I accidentally squashed the optimisation last round so update
   commit message with the details.
---
  docs/devel/tcg-plugins.rst |  17 +-
  contrib/plugins/execlog.c  | 316 +++--
  2 files changed, 281 insertions(+), 52 deletions(-)

diff --git a/docs/devel/tcg-plugins.rst b/docs/devel/tcg-plugins.rst
index 81dcd43a612..fa7421279f5 100644
--- a/docs/devel/tcg-plugins.rst
+++ b/docs/devel/tcg-plugins.rst
@@ -497,6 +497,22 @@ arguments if required::
$ qemu-system-arm $(QEMU_ARGS) \
  -plugin ./contrib/plugins/libexeclog.so,ifilter=st1w,afilter=0x40001808 
-d plugin
  
+This plugin can also dump registers when they change value. Specify the name of the

+registers with multiple ``reg`` options. You can also use glob style matching 
if you wish::
+
+  $ qemu-system-arm $(QEMU_ARGS) \
+-plugin ./contrib/plugins/libexeclog.so,reg=\*_el2,reg=sp -d plugin
+
+Be aware that each additional register to check will slow down
+execution quite considerably. You can optimise the number of register
+checks done by using the rdisas option. This will only instrument
+instructions that mention the registers in question in disassembly.
+This is not foolproof as some instructions implicitly change
+instructions. You can use the ifilter to catch these cases:
+
+  $ qemu-system-arm $(QEMU_ARGS) \
+-plugin 
./contrib/plugins/libexeclog.so,ifilter=msr,ifilter=blr,reg=x30,reg=\*_el1,rdisas=on
+
  - contrib/plugins/cache.c
  
  Cache modelling plugin that measures the performance of a given L1 cache

@@ -583,4 +599,3 @@ The following API is generated from the inline 
documentation in
  include the full kernel-doc annotations.
  
  .. kernel-doc:: include/qemu/qemu-plugin.h

-
diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
index f262eeb..dd7168cb548 100644
--- a/contrib/plugins/execlog.c
+++ b/contrib/plugins/execlog.c
@@ -1,7 +1,7 @@
  /*
   * Copyright (C) 2021, Alexandre Iooss 
   *
- * Log instruction execution with memory access.
+ * Log instruction execution with memory access and register changes
   *
   * License: GNU GPL, version 2 or later.
   *   See the COPYING file in the top-level directory.
@@ -15,29 +15,40 @@
  
  #include 
  
+typedef struct {

+struct qemu_plugin_register *handle;
+GByteArray *last;
+GByteArray *new;
+const char *name;
+} Register;
+
+typedef struct CPU {
+/* Store last executed instruction on each vCPU as a GString */
+GString *last_exec;
+/* Ptr array of Register */
+GPtrArray *registers;
+} CPU;
+
  QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
  
-/* Store last executed instruction on each vCPU as a GString */

-static GPtrArray *last_exec;
+static GArray *cpus;
  static GRWLock expand_array_lock;
  
  static GPtrArray *imatches;

  static GArray *amatches;
+static GPtrArray *rmatches;
+static bool disas_assist;
+static GMutex add_reg_name_lock;
+static GPtrArray *all_reg_names;
  
-/*

- * Expand last_exec array.
- *
- * As we could have multiple threads trying to do this we need to
- * serialise the expansion under a lock.
- */
-static void expand_last_exec(int cpu_index)
+static CPU *get_cpu(int vcpu_index)
  {
-g_rw_lock_writer_lock(_array_lock);
-while (cpu_index >= last_exec->len) {
-GString *s = g_string_new(NULL);
-g_ptr_array_add(last_exec, s);
-}
-g_rw_lock_writer_unlock(_array_lock);
+CPU *c;
+g_rw_lock_reader_lock(_array_lock);
+c = _array_index(cpus, CPU, vcpu_index);
+g_rw_lock_reader_unlock(_array_lock);
+
+return c;
  }
  
  /**

@@ -46,13 +57,10 @@ static void expand_last_exec(int cpu_index)
  static void vcpu_mem(unsigned int cpu_index, qemu_plugin_meminfo_t info,

RE: [PATCH RFCv2 1/8] backends/iommufd: Introduce helper function iommufd_device_get_hw_capabilities()

2024-02-25 Thread Duan, Zhenzhong
Hi Joao,

>-Original Message-
>From: Joao Martins 
>Subject: [PATCH RFCv2 1/8] backends/iommufd: Introduce helper function
>iommufd_device_get_hw_capabilities()
>
>The new helper will fetch vendor agnostic IOMMU capabilities supported
>both by hardware and software. Right now it is only iommu dirty
>tracking.
>
>Signed-off-by: Joao Martins 
>---
> backends/iommufd.c   | 25 +
> include/sysemu/iommufd.h |  2 ++
> 2 files changed, 27 insertions(+)
>
>diff --git a/backends/iommufd.c b/backends/iommufd.c
>index d92791bba935..8486894f1b3f 100644
>--- a/backends/iommufd.c
>+++ b/backends/iommufd.c
>@@ -237,3 +237,28 @@ void iommufd_device_init(IOMMUFDDevice *idev)
> host_iommu_base_device_init(>base, HID_IOMMUFD,
> sizeof(IOMMUFDDevice));
> }
>+
>+int iommufd_device_get_hw_capabilities(IOMMUFDDevice *idev, uint64_t
>*caps,
>+   Error **errp)
>+{
>+struct iommu_hw_info info = {
>+.size = sizeof(info),
>+.flags = 0,
>+.dev_id = idev->devid,
>+.data_len = 0,
>+.__reserved = 0,
>+.data_uptr = 0,
>+.out_capabilities = 0,
>+};
>+int ret;
>+
>+ret = ioctl(idev->iommufd->fd, IOMMU_GET_HW_INFO, );
>+if (ret) {
>+error_setg_errno(errp, errno,
>+ "Failed to get hardware info capabilities");
>+} else {
>+*caps = info.out_capabilities;
>+}
>+
>+return ret;
>+}

This helper is redundant with 
https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00031.html
We have to get other elements in info in nesting series, so mind using that 
helper
Instead to avoid redundancy? I can move that patch ahead for your usage.

Thanks
Zhenzhong

>diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h
>index c3f346976039..4afe97307dbe 100644
>--- a/include/sysemu/iommufd.h
>+++ b/include/sysemu/iommufd.h
>@@ -47,4 +47,6 @@ typedef struct IOMMUFDDevice {
> } IOMMUFDDevice;
>
> void iommufd_device_init(IOMMUFDDevice *idev);
>+int iommufd_device_get_hw_capabilities(IOMMUFDDevice *idev, uint64_t
>*caps,
>+   Error **errp);
> #endif
>--
>2.39.3




Re: [PATCH v2 1/2] system/memory.c: support unaligned access

2024-02-25 Thread Tomoyuki Hirose
Hello,
I would be happy if you could give me some comments.

ping.

On Thu, Feb 1, 2024 at 5:14 PM Tomoyuki HIROSE
 wrote:
>
> The previous code ignored 'impl.unaligned' and handled unaligned accesses
> as is. But this implementation cannot emulate specific registers of some
> devices that allow unaligned access such as xHCI Host Controller Capability
> Registers.
> This commit checks 'impl.unaligned' and if it is false, QEMU emulates
> unaligned access with multiple aligned access.
>
> Signed-off-by: Tomoyuki HIROSE 
> ---
>  system/memory.c | 38 +-
>  1 file changed, 25 insertions(+), 13 deletions(-)
>
> diff --git a/system/memory.c b/system/memory.c
> index a229a79988..a7ca0c9f54 100644
> --- a/system/memory.c
> +++ b/system/memory.c
> @@ -535,10 +535,17 @@ static MemTxResult access_with_adjusted_size(hwaddr 
> addr,
>MemTxAttrs attrs)
>  {
>  uint64_t access_mask;
> +unsigned access_mask_shift;
> +unsigned access_mask_start_offset;
> +unsigned access_mask_end_offset;
>  unsigned access_size;
> -unsigned i;
>  MemTxResult r = MEMTX_OK;
>  bool reentrancy_guard_applied = false;
> +bool is_big_endian = memory_region_big_endian(mr);
> +signed start_diff;
> +signed current_offset;
> +signed access_shift;
> +hwaddr current_addr;
>
>  if (!access_size_min) {
>  access_size_min = 1;
> @@ -560,19 +567,24 @@ static MemTxResult access_with_adjusted_size(hwaddr 
> addr,
>  reentrancy_guard_applied = true;
>  }
>
> -/* FIXME: support unaligned access? */
>  access_size = MAX(MIN(size, access_size_max), access_size_min);
> -access_mask = MAKE_64BIT_MASK(0, access_size * 8);
> -if (memory_region_big_endian(mr)) {
> -for (i = 0; i < size; i += access_size) {
> -r |= access_fn(mr, addr + i, value, access_size,
> -(size - access_size - i) * 8, access_mask, attrs);
> -}
> -} else {
> -for (i = 0; i < size; i += access_size) {
> -r |= access_fn(mr, addr + i, value, access_size, i * 8,
> -access_mask, attrs);
> -}
> +start_diff = mr->ops->impl.unaligned ? 0 : addr & (access_size - 1);
> +current_addr = addr - start_diff;
> +for (current_offset = -start_diff; current_offset < (signed)size;
> + current_offset += access_size, current_addr += access_size) {
> +access_shift = is_big_endian
> +  ? (signed)size - (signed)access_size - 
> current_offset
> +  : current_offset;
> +access_mask_shift = current_offset > 0 ? 0 : -current_offset;
> +access_mask_start_offset = current_offset > 0 ? current_offset : 0;
> +access_mask_end_offset = current_offset + access_size > size
> + ? size
> + : current_offset + access_size;
> +access_mask = MAKE_64BIT_MASK(access_mask_shift * 8,
> +(access_mask_end_offset - access_mask_start_offset) * 8);
> +
> +r |= access_fn(mr, current_addr, value, access_size, access_shift * 
> 8,
> +   access_mask, attrs);
>  }
>  if (mr->dev && reentrancy_guard_applied) {
>  mr->dev->mem_reentrancy_guard.engaged_in_io = false;
> --
> 2.39.2
>



RE: [PATCH v2 0/4] RISC-V: Modularize common match conditions for trigger

2024-02-25 Thread 張哲嘉
Hi Alistair,

> -Original Message-
> From: Alistair Francis 
> Sent: Monday, February 26, 2024 2:45 PM
> To: Alvin Che-Chia Chang(張哲嘉) 
> Cc: qemu-ri...@nongnu.org; qemu-devel@nongnu.org;
> alistair.fran...@wdc.com; bin.m...@windriver.com; liwei1...@gmail.com;
> dbarb...@ventanamicro.com; zhiwei_...@linux.alibaba.com
> Subject: Re: [PATCH v2 0/4] RISC-V: Modularize common match conditions for
> trigger
>
> [EXTERNAL MAIL 外部信件]
>
> On Mon, Feb 26, 2024 at 11:16 AM Alvin Che-Chia Chang(張哲嘉)
>  wrote:
> >
> > Hi Alistair,
> >
> > > -Original Message-
> > > From: Alistair Francis 
> > > Sent: Monday, February 26, 2024 8:25 AM
> > > To: Alvin Che-Chia Chang(張哲嘉) 
> > > Cc: qemu-ri...@nongnu.org; qemu-devel@nongnu.org;
> > > alistair.fran...@wdc.com; bin.m...@windriver.com;
> > > liwei1...@gmail.com; dbarb...@ventanamicro.com;
> > > zhiwei_...@linux.alibaba.com
> > > Subject: Re: [PATCH v2 0/4] RISC-V: Modularize common match
> > > conditions for trigger
> > >
> > > [EXTERNAL MAIL 外部信件]
> > >
> > > On Fri, Feb 23, 2024 at 12:22 PM Alvin Chang via
> > > 
> > > wrote:
> > > >
> > > > According to RISC-V Debug specification, the enabled privilege
> > > > levels of
> > >
> > > Can you specify what version of the debug spec?
> >
> > In general, this series does not add any new functionalities.
> > The original implementation has duplicated code in type 2/3/6 triggers.
> > I just eliminated those code and modularized them to be
> trigger_common_match().
> > Besides, we may want to check other conditions in the future, so this 
> > function
> can be used for those purposes.
>
> Ah, you are right. I just skimmed the message
>
> >
> > When I track the commit history, it seems the code is submitted in the
> following commits two years ago:
> >
> https://github.com/qemu/qemu/commit/95799e36c15a9ab602a388491c40f68
> 60f
> > 6ae8bf
> >
> https://github.com/qemu/qemu/commit/b5f6379d134bd201d52380c73ff7356
> 5e6
> > a4321e
> >
> https://github.com/qemu/qemu/commit/c32461d8eeb17490b1b1e969e2ce8f1
> ecd
> > 83bfbb
> >
> https://github.com/qemu/qemu/commit/c472c142a7552f5b0e40378d5643a28
> 10e
> > f1b111
> >
> > Since they mentioned the "type 6" trigger and "Sdtrig" extension, I
> > assume current implementation is based on Debug Spec version 1.0 There
> > is no type 6 trigger and Sdtrig extension in Debug Spec version 0.13
>
> Yeah, we are a weird mix-match of the two unfortunately. Which is why I
> wanted to be explicit about which debug spec version you are targeting.

Done, I explicitly mention the version of Debug Spec in the commit message.
Please check patch v3.

>
> >
> > Sincerely,
> > Alvin Chang
> >
> > >
> > > Ideally if you can link directly to the PDF that would be very useful.
> > > There are multiple versions so it's hard to keep track of.
> > >
> > > Alistair
> > >
> > > > the trigger is common match conditions for all the types of the trigger.
> > > > This series modularize the code for checking the privilege levels
> > > > of type 2/3/6 triggers by implementing functions
> > > > trigger_common_match() and trigger_priv_match().
> > > >
> > > > Additional match conditions, such as CSR tcontrol and textra, can
> > > > be further implemented into trigger_common_match() in the future.
> > > >
> > > > Changes from v1:
> > > > - Fix typo
> > > > - Add commit description for changing behavior of looping the triggers
> > > >   when we check type 2 triggers.
> > > >
> > > > Alvin Chang (4):
> > > >   target/riscv: Add functions for common matching conditions of trigger
> > > >   target/riscv: Apply modularized matching conditions for breakpoint
> > > >   target/riscv: Apply modularized matching conditions for watchpoint
> > > >   target/riscv: Apply modularized matching conditions for icount
> > > > trigger
> > > >
> > > >  target/riscv/debug.c | 124
> > > > +--
> > > >  1 file changed, 83 insertions(+), 41 deletions(-)
> > > >
> > > > --
> > > > 2.34.1
> > > >
> > > >
> > CONFIDENTIALITY NOTICE:
> >
> > This e-mail (and its attachments) may contain confidential and legally
> privileged information or information protected from disclosure. If you are 
> not
> the intended recipient, you are hereby notified that any disclosure, copying,
> distribution, or use of the information contained herein is strictly 
> prohibited. In
> this case, please immediately notify the sender by return e-mail, delete the
> message (and any accompanying documents) and destroy all printed hard
> copies. Thank you for your cooperation.
> >
> > Copyright ANDES TECHNOLOGY CORPORATION - All Rights Reserved.
>
> I'm not sure what you want me to do here

Oh.. It automatically shows up when I send email out of our company server.
Please ignore it here.

>
> Alistair
CONFIDENTIALITY NOTICE:

This e-mail (and its attachments) may contain confidential and legally 
privileged information or information protected from disclosure. If you are not 
the intended recipient, you are hereby notified that 

Re: [PATCH v4 20/34] migration/multifd: Add outgoing QIOChannelFile support

2024-02-25 Thread Peter Xu
On Tue, Feb 20, 2024 at 07:41:24PM -0300, Fabiano Rosas wrote:
> +int file_send_channel_destroy(QIOChannel *ioc)
> +{
> +if (ioc) {
> +qio_channel_close(ioc, NULL);
> +}
> +g_free(outgoing_args.fname);
> +outgoing_args.fname = NULL;

Ah another thing: we may want to have file_cleanup_outgoing_migration()
from the 1st day if possible..

https://lore.kernel.org/all/20240222095301.171137-5-pet...@redhat.com/

The other one was already in my queue, so feel free to rebase to
migration-next directly if before the next pull (I'll remember to push
soon; now it is in -staging).

Thanks,

-- 
Peter Xu




Re: [PATCH v2 1/7] migration/multifd: Add new migration option zero-page-detection.

2024-02-25 Thread Wang, Lei
On 2/17/2024 6:39, Hao Xiang wrote:
> This new parameter controls where the zero page checking is running.
> 1. If this parameter is set to 'legacy', zero page checking is
> done in the migration main thread.
> 2. If this parameter is set to 'none', zero page checking is disabled.
> 
> Signed-off-by: Hao Xiang 
> ---
>  hw/core/qdev-properties-system.c| 10 ++
>  include/hw/qdev-properties-system.h |  4 
>  migration/migration-hmp-cmds.c  |  9 +
>  migration/options.c | 21 
>  migration/options.h |  1 +
>  migration/ram.c |  4 
>  qapi/migration.json | 30 ++---
>  7 files changed, 76 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/core/qdev-properties-system.c 
> b/hw/core/qdev-properties-system.c
> index 1a396521d5..63843f18b5 100644
> --- a/hw/core/qdev-properties-system.c
> +++ b/hw/core/qdev-properties-system.c
> @@ -679,6 +679,16 @@ const PropertyInfo qdev_prop_mig_mode = {
>  .set_default_value = qdev_propinfo_set_default_value_enum,
>  };
>  
> +const PropertyInfo qdev_prop_zero_page_detection = {
> +.name = "ZeroPageDetection",
> +.description = "zero_page_detection values, "
> +   "multifd,legacy,none",

Nit: Maybe multifd/legacy/none?



[Bug 2055003] Re: Qemu cmdline core dumped with more(8193 or more) cpus

2024-02-25 Thread Frank Heimes
** Also affects: qemu
   Importance: Undecided
   Status: New

** No longer affects: qemu

** Also affects: ubuntu-power-systems
   Importance: Undecided
   Status: New

** Changed in: ubuntu-power-systems
 Assignee: (unassigned) => Ubuntu on IBM Power Systems Bug Triage 
(ubuntu-power-triage)

** Changed in: qemu (Ubuntu)
 Assignee: Ubuntu on IBM Power Systems Bug Triage (ubuntu-power-triage) => 
(unassigned)

** Changed in: ubuntu-power-systems
   Importance: Undecided => High

** Changed in: qemu (Ubuntu)
   Importance: Undecided => High

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/2055003

Title:
  Qemu cmdline core dumped with more(8193 or more) cpus

Status in The Ubuntu-power-systems project:
  New
Status in qemu package in Ubuntu:
  New

Bug description:
  ---Debugger---
  A debugger is not configured
   
  ---Steps to Reproduce---
   
  ---Problem Description---
   Qemu cmdline core dumped with more(8193 or more) cpus
   
  ---Debugger---
  A debugger is not configured
   
  ---Steps to Reproduce---
   Qemu cmdline core dumped when more number of CPUs were given.

  
  [root@ltcmihawk39 ~]# qemu-system-ppc64 -accel tcg -smp 10,maxcpus=9000
  **
  ERROR:../tcg/region.c:782:tcg_region_init: assertion failed: (region_size >= 
2 * page_size)
  Bail out! ERROR:../tcg/region.c:782:tcg_region_init: assertion failed: 
(region_size >= 2 * page_size)
  Aborted (core dumped)

  Expected Result:
  Warning message like "Number of cpus requested exceeds the cpus supported"

  Actual Result:
  core dumped

  Steps to Reproduce:
  

  1. Clone the upstream qemu from https://gitlab.com/qemu-project/qemu.git
  2. Compile qemu with below steps.
  cd qemu/
  git submodule init
  git submodule update --recursive
  ./configure --target-list=ppc64-softmmu --prefix=/usr
  make
  make install
  3. set maxcpus=8193 or more

  
  [root@ltcmihawk39 ~]# qemu-system-ppc64 --version
  QEMU emulator version 8.0.94 (v8.1.0-rc4)
  Copyright (c) 2003-2023 Fabrice Bellard and the QEMU Project developers

  NOTE: This behavior is observed only when qemu is built without disabling the 
tcg.
   
  Contact Information = sthou...@in.ibm.com 
   
  Machine Type = x 
   
  ---uname output---
  x

  Action needed

  Our IBM Dev want to include this patch in latest Canonical distro.

  Need the distro to review and integrate fixes provided by IBM

  https://github.com/qemu/qemu/commit/c4f91d7b7be76c47015521ab0109c6e998a369b0

  Need to include this commit in latest Canonical distro.

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu-power-systems/+bug/2055003/+subscriptions




Re: support on risc-v 128bits

2024-02-25 Thread Philippe Mathieu-Daudé

On 26/2/24 00:57, Alistair Francis wrote:

On Mon, Feb 26, 2024 at 9:30 AM Jean-Christophe Énée
 wrote:


hi,
i would like developpe my OS on risc-v 128 bits.
after search the support isn´t fully operational


We have some basic 128-bit support, but it isn't complete. The RISC-V
spec states:

```
The design of the RV128I base ISA is not yet complete, and while much
of the remainder of this specification is expected to apply to RV128,
this version of the document focuses only on RV32 and RV64
```

so the spec isn't finished either. AFAIK there is also no guest
software we can use for testing.



how can i help, and in the same learn risc-v 128 bits


At this point there isn't really too much to do. There is some basic
support, so maybe you could try and port your OS to that? I'm not sure
how you would compile it for 128-bit support though, as I don't think
any compilers support 128-bits.


You can also have a look at TinyEMU from Fabrice Bellard:

https://bellard.org/tinyemu/readme.txt

- RISC-V system emulator supporting the RV128IMAFDQC base ISA (user
  level ISA version 2.2, priviledged architecture version 1.10)
  including:

  - 32/64/128 bit integer registers
  - 32/64/128 bit floating point instructions
  - Compressed instructions
  - dynamic XLEN change

...

4) Technical notes
--

4.1) 128 bit support

The RISC-V specification does not define all the instruction encodings
for the 128 bit integer and floating point operations. The missing
ones were interpolated from the 32 and 64 ones.

Unfortunately there is no RISC-V 128 bit toolchain nor OS now
(volunteers for the Linux port ?), so rv128test.bin may be the first
128 bit code for RISC-V !




Re: [PATCH 09/10] usb: extract sysbus-ohci to a separate file

2024-02-25 Thread Thomas Huth

On 23/02/2024 13.44, Paolo Bonzini wrote:

Split the sysbus version to a separate file so that it is not
included in PCI-only machines, and adjust Kconfig for machines
that do need sysbus-ohci.  The copyrights are based on the
time and employer of balrog and Paul Brook's contributions.

While adjusting the SM501 dependency, move it to the right place
instead of keeping it in the R4D machine.

Signed-off-by: Paolo Bonzini 
---
  hw/usb/hcd-ohci-sysbus.c | 91 
  hw/usb/hcd-ohci.c| 58 
  hw/arm/Kconfig   | 12 +++--
  hw/display/Kconfig   |  1 +
  hw/ppc/Kconfig   |  2 +-
  hw/sh4/Kconfig   |  1 -
  hw/usb/Kconfig   |  4 ++
  hw/usb/meson.build   |  1 +
  8 files changed, 105 insertions(+), 65 deletions(-)
  create mode 100644 hw/usb/hcd-ohci-sysbus.c

diff --git a/hw/usb/hcd-ohci-sysbus.c b/hw/usb/hcd-ohci-sysbus.c
new file mode 100644
index 000..4e4481232b6
--- /dev/null
+++ b/hw/usb/hcd-ohci-sysbus.c
@@ -0,0 +1,91 @@
+/*
+ * QEMU USB OHCI Emulation
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Copyright (c) 2010 CodeSourcery
+ * Copyright (c) 2024 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "hw/usb.h"
+#include "migration/vmstate.h"
+#include "hw/sysbus.h"
+#include "hw/qdev-dma.h"
+#include "hw/qdev-properties.h"
+#include "trace.h"
+#include "hcd-ohci.h"
+
+
+static void ohci_realize_pxa(DeviceState *dev, Error **errp)


Maybe this could be renamed to ohci_sysbs_realize() now since the code is 
used in non-pxa devices nowadays, too?


Anyway:
Reviewed-by: Thomas Huth 




Re: [PATCH v4 20/34] migration/multifd: Add outgoing QIOChannelFile support

2024-02-25 Thread Peter Xu
On Tue, Feb 20, 2024 at 07:41:24PM -0300, Fabiano Rosas wrote:
> Allow multifd to open file-backed channels. This will be used when
> enabling the fixed-ram migration stream format which expects a
> seekable transport.
> 
> The QIOChannel read and write methods will use the preadv/pwritev
> versions which don't update the file offset at each call so we can
> reuse the fd without re-opening for every channel.
> 
> Contrary to the socket migration, the file migration doesn't need an
> asynchronous channel creation process, so expose
> multifd_channel_connect() and call it directly.
> 
> Note that this is just setup code and multifd cannot yet make use of
> the file channels.
> 
> Signed-off-by: Fabiano Rosas 
> ---
>  migration/file.c| 40 ++--
>  migration/file.h|  5 +
>  migration/multifd.c | 27 ++-
>  migration/multifd.h |  2 ++
>  4 files changed, 67 insertions(+), 7 deletions(-)
> 
> diff --git a/migration/file.c b/migration/file.c
> index 22d052a71f..ac9f6ae40a 100644
> --- a/migration/file.c
> +++ b/migration/file.c
> @@ -12,12 +12,17 @@
>  #include "channel.h"
>  #include "file.h"
>  #include "migration.h"
> +#include "multifd.h"
>  #include "io/channel-file.h"
>  #include "io/channel-util.h"
>  #include "trace.h"
>  
>  #define OFFSET_OPTION ",offset="
>  
> +static struct FileOutgoingArgs {
> +char *fname;
> +} outgoing_args;
> +
>  /* Remove the offset option from @filespec and return it in @offsetp. */
>  
>  int file_parse_offset(char *filespec, uint64_t *offsetp, Error **errp)
> @@ -37,6 +42,34 @@ int file_parse_offset(char *filespec, uint64_t *offsetp, 
> Error **errp)
>  return 0;
>  }
>  
> +int file_send_channel_destroy(QIOChannel *ioc)
> +{
> +if (ioc) {
> +qio_channel_close(ioc, NULL);
> +}
> +g_free(outgoing_args.fname);
> +outgoing_args.fname = NULL;
> +
> +return 0;
> +}
> +
> +bool file_send_channel_create(gpointer opaque, Error **errp)
> +{
> +QIOChannelFile *ioc;
> +int flags = O_WRONLY;
> +
> +ioc = qio_channel_file_new_path(outgoing_args.fname, flags, 0, errp);
> +if (!ioc) {
> +return false;
> +}
> +
> +if (!multifd_channel_connect(opaque, QIO_CHANNEL(ioc), errp)) {
> +return false;
> +}
> +
> +return true;
> +}
> +
>  void file_start_outgoing_migration(MigrationState *s,
> FileMigrationArgs *file_args, Error 
> **errp)
>  {
> @@ -44,15 +77,18 @@ void file_start_outgoing_migration(MigrationState *s,
>  g_autofree char *filename = g_strdup(file_args->filename);
>  uint64_t offset = file_args->offset;
>  QIOChannel *ioc;
> +int flags = O_CREAT | O_TRUNC | O_WRONLY;
> +mode_t mode = 0660;
>  
>  trace_migration_file_outgoing(filename);
>  
> -fioc = qio_channel_file_new_path(filename, O_CREAT | O_WRONLY | O_TRUNC,
> - 0600, errp);
> +fioc = qio_channel_file_new_path(filename, flags, mode, errp);

This change seems irrelevant, could be squashed into the previous patch
when introduced?

>  if (!fioc) {
>  return;
>  }
>  
> +outgoing_args.fname = g_strdup(filename);
> +
>  ioc = QIO_CHANNEL(fioc);
>  if (offset && qio_channel_io_seek(ioc, offset, SEEK_SET, errp) < 0) {
>  return;
> diff --git a/migration/file.h b/migration/file.h
> index 37d6a08bfc..90794b494b 100644
> --- a/migration/file.h
> +++ b/migration/file.h
> @@ -9,10 +9,15 @@
>  #define QEMU_MIGRATION_FILE_H
>  
>  #include "qapi/qapi-types-migration.h"
> +#include "io/task.h"
> +#include "channel.h"
>  
>  void file_start_incoming_migration(FileMigrationArgs *file_args, Error 
> **errp);
>  
>  void file_start_outgoing_migration(MigrationState *s,
> FileMigrationArgs *file_args, Error 
> **errp);
>  int file_parse_offset(char *filespec, uint64_t *offsetp, Error **errp);
> +
> +bool file_send_channel_create(gpointer opaque, Error **errp);
> +int file_send_channel_destroy(QIOChannel *ioc);
>  #endif
> diff --git a/migration/multifd.c b/migration/multifd.c
> index 45a0c7aaa8..507b497d52 100644
> --- a/migration/multifd.c
> +++ b/migration/multifd.c
> @@ -17,6 +17,7 @@
>  #include "exec/ramblock.h"
>  #include "qemu/error-report.h"
>  #include "qapi/error.h"
> +#include "file.h"
>  #include "ram.h"
>  #include "migration.h"
>  #include "migration-stats.h"
> @@ -28,6 +29,7 @@
>  #include "threadinfo.h"
>  #include "options.h"
>  #include "qemu/yank.h"
> +#include "io/channel-file.h"
>  #include "io/channel-socket.h"
>  #include "yank_functions.h"
>  
> @@ -680,6 +682,9 @@ static void multifd_send_terminate_threads(void)
>  
>  static int multifd_send_channel_destroy(QIOChannel *send)
>  {
> +if (!multifd_use_packets()) {
> +return file_send_channel_destroy(send);
> +}
>  return socket_send_channel_destroy(send);
>  }
>  
> @@ -959,9 +964,8 @@ static bool 

[PATCH v3 0/4] RISC-V: Modularize common match conditions for trigger

2024-02-25 Thread Alvin Chang via
According to latest RISC-V Debug specification version 1.0 [1], the
enabled privilege levels of the trigger is common match conditions for
all the types of the trigger.

This series modularize the code for checking the privilege levels of
type 2/3/6 triggers by implementing functions trigger_common_match()
and trigger_priv_match().

Additional match conditions, such as CSR tcontrol and textra, can be
further implemented into trigger_common_match() in the future.

[1]: https://github.com/riscv/riscv-debug-spec/releases/tag/1.0.0-rc1-asciidoc

Changes from v2:
- Explicitly mention the targeting version of RISC-V Debug Spec.

Changes from v1:
- Fix typo
- Add commit description for changing behavior of looping the triggers
  when we check type 2 triggers.

Alvin Chang (4):
  target/riscv: Add functions for common matching conditions of trigger
  target/riscv: Apply modularized matching conditions for breakpoint
  target/riscv: Apply modularized matching conditions for watchpoint
  target/riscv: Apply modularized matching conditions for icount trigger

 target/riscv/debug.c | 124 +--
 1 file changed, 83 insertions(+), 41 deletions(-)

-- 
2.34.1




[PATCH v3 2/4] target/riscv: Apply modularized matching conditions for breakpoint

2024-02-25 Thread Alvin Chang via
We have implemented trigger_common_match(), which checks if the enabled
privilege levels of the trigger match CPU's current privilege level.
Remove the related code in riscv_cpu_debug_check_breakpoint() and invoke
trigger_common_match() to check the privilege levels of the type 2 and
type 6 triggers for the breakpoints.

This commit also changes the behavior of looping the triggers. In
previous implementation, if we have a type 2 trigger and
env->virt_enabled is true, we directly return false to stop the loop.
Now we keep looping all the triggers until we find a matched trigger.

Only the execution bit and the executed PC should be futher checked in
riscv_cpu_debug_check_breakpoint().

Signed-off-by: Alvin Chang 
---
 target/riscv/debug.c | 26 ++
 1 file changed, 6 insertions(+), 20 deletions(-)

diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 3891236b82..b7b0fa8945 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -855,21 +855,17 @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
 for (i = 0; i < RV_MAX_TRIGGERS; i++) {
 trigger_type = get_trigger_type(env, i);
 
+if (!trigger_common_match(env, trigger_type, i)) {
+continue;
+}
+
 switch (trigger_type) {
 case TRIGGER_TYPE_AD_MATCH:
-/* type 2 trigger cannot be fired in VU/VS mode */
-if (env->virt_enabled) {
-return false;
-}
-
 ctrl = env->tdata1[i];
 pc = env->tdata2[i];
 
 if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
-/* check U/S/M bit against current privilege level */
-if ((ctrl >> 3) & BIT(env->priv)) {
-return true;
-}
+return true;
 }
 break;
 case TRIGGER_TYPE_AD_MATCH6:
@@ -877,17 +873,7 @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
 pc = env->tdata2[i];
 
 if ((ctrl & TYPE6_EXEC) && (bp->pc == pc)) {
-if (env->virt_enabled) {
-/* check VU/VS bit against current privilege level */
-if ((ctrl >> 23) & BIT(env->priv)) {
-return true;
-}
-} else {
-/* check U/S/M bit against current privilege level */
-if ((ctrl >> 3) & BIT(env->priv)) {
-return true;
-}
-}
+return true;
 }
 break;
 default:
-- 
2.34.1




[PATCH v3 4/4] target/riscv: Apply modularized matching conditions for icount trigger

2024-02-25 Thread Alvin Chang via
We have implemented trigger_common_match(), which checks if the enabled
privilege levels of the trigger match CPU's current privilege level. We
can invoke trigger_common_match() to check the privilege levels of the
type 3 triggers.

Signed-off-by: Alvin Chang 
---
 target/riscv/debug.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 9f9f332019..eb45e2c147 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -624,7 +624,7 @@ void helper_itrigger_match(CPURISCVState *env)
 if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
 continue;
 }
-if (check_itrigger_priv(env, i)) {
+if (!trigger_common_match(env, TRIGGER_TYPE_INST_CNT, i)) {
 continue;
 }
 count = itrigger_get_count(env, i);
-- 
2.34.1




[PATCH v3 3/4] target/riscv: Apply modularized matching conditions for watchpoint

2024-02-25 Thread Alvin Chang via
We have implemented trigger_common_match(), which checks if the enabled
privilege levels of the trigger match CPU's current privilege level.
Remove the related code in riscv_cpu_debug_check_watchpoint() and invoke
trigger_common_match() to check the privilege levels of the type 2 and
type 6 triggers for the watchpoints.

This commit also changes the behavior of looping the triggers. In
previous implementation, if we have a type 2 trigger and
env->virt_enabled is true, we directly return false to stop the loop.
Now we keep looping all the triggers until we find a matched trigger.

Only load/store bits and loaded/stored address should be further checked
in riscv_cpu_debug_check_watchpoint().

Signed-off-by: Alvin Chang 
---
 target/riscv/debug.c | 26 ++
 1 file changed, 6 insertions(+), 20 deletions(-)

diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index b7b0fa8945..9f9f332019 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -899,13 +899,12 @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, 
CPUWatchpoint *wp)
 for (i = 0; i < RV_MAX_TRIGGERS; i++) {
 trigger_type = get_trigger_type(env, i);
 
+if (!trigger_common_match(env, trigger_type, i)) {
+continue;
+}
+
 switch (trigger_type) {
 case TRIGGER_TYPE_AD_MATCH:
-/* type 2 trigger cannot be fired in VU/VS mode */
-if (env->virt_enabled) {
-return false;
-}
-
 ctrl = env->tdata1[i];
 addr = env->tdata2[i];
 flags = 0;
@@ -918,10 +917,7 @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, 
CPUWatchpoint *wp)
 }
 
 if ((wp->flags & flags) && (wp->vaddr == addr)) {
-/* check U/S/M bit against current privilege level */
-if ((ctrl >> 3) & BIT(env->priv)) {
-return true;
-}
+return true;
 }
 break;
 case TRIGGER_TYPE_AD_MATCH6:
@@ -937,17 +933,7 @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, 
CPUWatchpoint *wp)
 }
 
 if ((wp->flags & flags) && (wp->vaddr == addr)) {
-if (env->virt_enabled) {
-/* check VU/VS bit against current privilege level */
-if ((ctrl >> 23) & BIT(env->priv)) {
-return true;
-}
-} else {
-/* check U/S/M bit against current privilege level */
-if ((ctrl >> 3) & BIT(env->priv)) {
-return true;
-}
-}
+return true;
 }
 break;
 default:
-- 
2.34.1




[PATCH v3 1/4] target/riscv: Add functions for common matching conditions of trigger

2024-02-25 Thread Alvin Chang via
According to RISC-V Debug specification version 1.0 [1], there are
several common matching conditions before firing a trigger, including
the enabled privilege levels of the trigger.

This commit adds trigger_common_match() to prepare the common matching
conditions for the type 2/3/6 triggers. For now, we just implement
trigger_priv_match() to check if the enabled privilege levels of the
trigger match CPU's current privilege level.

[1]: https://github.com/riscv/riscv-debug-spec/releases/tag/1.0.0-rc1-asciidoc

Signed-off-by: Alvin Chang 
---
 target/riscv/debug.c | 70 
 1 file changed, 70 insertions(+)

diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index e30d99cc2f..3891236b82 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -241,6 +241,76 @@ static void do_trigger_action(CPURISCVState *env, 
target_ulong trigger_index)
 }
 }
 
+/*
+ * Check the privilege level of specific trigger matches CPU's current 
privilege
+ * level.
+ */
+static bool trigger_priv_match(CPURISCVState *env, trigger_type_t type,
+   int trigger_index)
+{
+target_ulong ctrl = env->tdata1[trigger_index];
+
+switch (type) {
+case TRIGGER_TYPE_AD_MATCH:
+/* type 2 trigger cannot be fired in VU/VS mode */
+if (env->virt_enabled) {
+return false;
+}
+/* check U/S/M bit against current privilege level */
+if ((ctrl >> 3) & BIT(env->priv)) {
+return true;
+}
+break;
+case TRIGGER_TYPE_AD_MATCH6:
+if (env->virt_enabled) {
+/* check VU/VS bit against current privilege level */
+if ((ctrl >> 23) & BIT(env->priv)) {
+return true;
+}
+} else {
+/* check U/S/M bit against current privilege level */
+if ((ctrl >> 3) & BIT(env->priv)) {
+return true;
+}
+}
+break;
+case TRIGGER_TYPE_INST_CNT:
+if (env->virt_enabled) {
+/* check VU/VS bit against current privilege level */
+if ((ctrl >> 25) & BIT(env->priv)) {
+return true;
+}
+} else {
+/* check U/S/M bit against current privilege level */
+if ((ctrl >> 6) & BIT(env->priv)) {
+return true;
+}
+}
+break;
+case TRIGGER_TYPE_INT:
+case TRIGGER_TYPE_EXCP:
+case TRIGGER_TYPE_EXT_SRC:
+qemu_log_mask(LOG_UNIMP, "trigger type: %d is not supported\n", type);
+break;
+case TRIGGER_TYPE_NO_EXIST:
+case TRIGGER_TYPE_UNAVAIL:
+qemu_log_mask(LOG_GUEST_ERROR, "trigger type: %d does not exist\n",
+  type);
+break;
+default:
+g_assert_not_reached();
+}
+
+return false;
+}
+
+/* Common matching conditions for all types of the triggers. */
+static bool trigger_common_match(CPURISCVState *env, trigger_type_t type,
+ int trigger_index)
+{
+return trigger_priv_match(env, type, trigger_index);
+}
+
 /* type 2 trigger */
 
 static uint32_t type2_breakpoint_size(CPURISCVState *env, target_ulong ctrl)
-- 
2.34.1




Re: [PATCH 04/10] mips/loongson3_virt: do not require CONFIG_USB

2024-02-25 Thread Thomas Huth

On 23/02/2024 13.44, Paolo Bonzini wrote:

Once the Kconfig for hw/mips is cleaned up, it will be possible to build a
binary that does not include any USB host controller and therefore that
does not include the code guarded by CONFIG_USB.  While the simpler
creation functions such as usb_create_simple can be inlined, this is not
true of usb_bus_find().  Remove it, replacing it with a search of the
single USB bus created by loongson3_virt_devices_init().

Signed-off-by: Paolo Bonzini 
---
  hw/mips/loongson3_virt.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index caedde2df00..b2a8b22b4ea 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -447,8 +447,9 @@ static inline void loongson3_virt_devices_init(MachineState 
*machine,
  
  if (defaults_enabled() && object_class_by_name("pci-ohci")) {

  pci_create_simple(pci_bus, -1, "pci-ohci");
-usb_create_simple(usb_bus_find(-1), "usb-kbd");
-usb_create_simple(usb_bus_find(-1), "usb-tablet");
+Object *usb_bus = object_resolve_type_unambiguous(TYPE_USB_BUS, 
_abort);


Please swap the "Object *usb_bus" and the "pci_create_simple" lines, so that 
the declaration is at the beginning of the block.


 Thomas




Re: [PATCH 03/10] sh4: r2d: do not use usb_bus_find()

2024-02-25 Thread Thomas Huth

On 23/02/2024 13.43, Paolo Bonzini wrote:

usb_bus_find() is always used with argument -1; it can be replaced with
a search of the single USB bus on the machine.

Suggested-by: Philippe Mathieu-Daudé 
Signed-off-by: Paolo Bonzini 
---
  hw/sh4/r2d.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index c73e8f49b8a..4d34ad00d93 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -244,6 +244,7 @@ static void r2d_init(MachineState *machine)
  SysBusDevice *busdev;
  MemoryRegion *address_space_mem = get_system_memory();
  PCIBus *pci_bus;
+USBBus *usb_bus;
  
  cpu = SUPERH_CPU(cpu_create(machine->cpu_type));

  env = >env;
@@ -312,7 +313,8 @@ static void r2d_init(MachineState *machine)
  pci_init_nic_devices(pci_bus, mc->default_nic);
  
  /* USB keyboard */

-usb_create_simple(usb_bus_find(-1), "usb-kbd");
+usb_bus = USB_BUS(object_resolve_type_unambiguous(TYPE_USB_BUS, 
_abort));
+usb_create_simple(usb_bus, "usb-kbd");
  
  /* Todo: register on board registers */

  memset(_params, 0, sizeof(boot_params));


Reviewed-by: Thomas Huth 




Re: [PATCH 02/10] ppc: sam460ex: do not use usb_bus_find()

2024-02-25 Thread Thomas Huth

On 23/02/2024 13.43, Paolo Bonzini wrote:

usb_bus_find() is always used with argument -1; it can be replaced with
a search of the single USB bus on the machine.

Suggested-by: Philippe Mathieu-Daudé 
Signed-off-by: Paolo Bonzini 
---
  hw/ppc/sam460ex.c | 6 --
  1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index 1e615b8d355..4d5655ab6b4 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -273,6 +273,7 @@ static void sam460ex_init(MachineState *machine)
  DeviceState *uic[4];
  int i;
  PCIBus *pci_bus;
+USBBus *usb_bus;
  PowerPCCPU *cpu;
  CPUPPCState *env;
  I2CBus *i2c;
@@ -420,8 +421,9 @@ static void sam460ex_init(MachineState *machine)
  sysbus_realize_and_unref(sbdev, _fatal);
  sysbus_mmio_map(sbdev, 0, 0x4bffd);
  sysbus_connect_irq(sbdev, 0, qdev_get_gpio_in(uic[2], 30));
-usb_create_simple(usb_bus_find(-1), "usb-kbd");
-usb_create_simple(usb_bus_find(-1), "usb-mouse");
+usb_bus = USB_BUS(object_resolve_type_unambiguous(TYPE_USB_BUS, 
_abort));
+usb_create_simple(usb_bus, "usb-kbd");
+usb_create_simple(usb_bus, "usb-mouse");
  
  /* PCIe buses */

  dev = qdev_new(TYPE_PPC460EX_PCIE_HOST);


Reviewed-by: Thomas Huth 




Re: [PATCH 01/10] acpi, qom: move object_resolve_type_unambiguous to core QOM

2024-02-25 Thread Thomas Huth

On 23/02/2024 13.43, Paolo Bonzini wrote:

object_resolve_type_unambiguous provides a useful functionality, that
is currently emulated for example by usb_bus_find().  Move it to core
code and add error reporting for increased generality.

Signed-off-by: Paolo Bonzini 
---
  include/qom/object.h | 13 +
  hw/i386/acpi-build.c | 19 ---
  qom/object.c | 16 
  3 files changed, 33 insertions(+), 15 deletions(-)


Reviewed-by: Thomas Huth 




Re: [RFC PATCH v3 06/21] target/arm: Add support for Non-maskable Interrupt

2024-02-25 Thread Jinjie Ruan via



On 2024/2/24 3:55, Richard Henderson wrote:
> On 2/23/24 00:32, Jinjie Ruan via wrote:
>> This only implements the external delivery method via the GICv3.
>>
>> Signed-off-by: Jinjie Ruan 
>> ---
>> v3:
>> - Not include CPU_INTERRUPT_NMI when FEAT_NMI not enabled
>> - Add ARM_CPU_VNMI.
>> - Refator nmi mask in arm_excp_unmasked().
>> - Test SCTLR_ELx.NMI for ALLINT mask for NMI.
>> ---
>>   target/arm/cpu-qom.h |  4 +++-
>>   target/arm/cpu.c | 54 
>>   target/arm/cpu.h |  4 
>>   target/arm/helper.c  |  2 ++
>>   4 files changed, 54 insertions(+), 10 deletions(-)
>>
>> diff --git a/target/arm/cpu-qom.h b/target/arm/cpu-qom.h
>> index 8e032691db..e0c9e18036 100644
>> --- a/target/arm/cpu-qom.h
>> +++ b/target/arm/cpu-qom.h
>> @@ -36,11 +36,13 @@ DECLARE_CLASS_CHECKERS(AArch64CPUClass, AARCH64_CPU,
>>   #define ARM_CPU_TYPE_SUFFIX "-" TYPE_ARM_CPU
>>   #define ARM_CPU_TYPE_NAME(name) (name ARM_CPU_TYPE_SUFFIX)
>>   -/* Meanings of the ARMCPU object's four inbound GPIO lines */
>> +/* Meanings of the ARMCPU object's six inbound GPIO lines */
>>   #define ARM_CPU_IRQ 0
>>   #define ARM_CPU_FIQ 1
>>   #define ARM_CPU_VIRQ 2
>>   #define ARM_CPU_VFIQ 3
>> +#define ARM_CPU_NMI 4
>> +#define ARM_CPU_VNMI 5
>>     /* For M profile, some registers are banked secure vs non-secure;
>>    * these are represented as a 2-element array where the first element
>> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
>> index 5fa86bc8d5..d40ada9c75 100644
>> --- a/target/arm/cpu.c
>> +++ b/target/arm/cpu.c
>> @@ -126,11 +126,20 @@ static bool arm_cpu_has_work(CPUState *cs)
>>   {
>>   ARMCPU *cpu = ARM_CPU(cs);
>>   -    return (cpu->power_state != PSCI_OFF)
>> -    && cs->interrupt_request &
>> -    (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD
>> - | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ | CPU_INTERRUPT_VSERR
>> - | CPU_INTERRUPT_EXITTB);
>> +    if (cpu_isar_feature(aa64_nmi, cpu)) {
>> +    return (cpu->power_state != PSCI_OFF)
>> +    && cs->interrupt_request &
>> +    (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD
>> + | CPU_INTERRUPT_NMI | CPU_INTERRUPT_VNMI
>> + | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ |
>> CPU_INTERRUPT_VSERR
>> + | CPU_INTERRUPT_EXITTB);
>> +    } else {
>> +    return (cpu->power_state != PSCI_OFF)
>> +    && cs->interrupt_request &
>> +    (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD
>> + | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ |
>> CPU_INTERRUPT_VSERR
>> + | CPU_INTERRUPT_EXITTB);
>> +    }
> 
> This can be factored better, to avoid repeating everything.
> 
> However, I am reconsidering my previous advice to ignore NMI if FEAT_NMI
> is not present.
> 
> Consider R_MHWBP, where IRQ with Superpriority, with SCTLR_ELx.NMI == 0,
> is masked identically with IRQ without Superpriority.  Moreover, if the
> GIC is configured so that FEAT_GICv3_NMI is only set if FEAT_NMI is set,
> then we won't ever see CPU_INTERRUPT_*NMI anyway.
> 
> So we might as well accept NMI here unconditionally.  But document this
> choice here with a comment.
> 
> 
>> @@ -678,13 +688,26 @@ static inline bool arm_excp_unmasked(CPUState
>> *cs, unsigned int excp_idx,
>>   return false;
>>   }
>>   +    if (cpu_isar_feature(aa64_nmi, env_archcpu(env))) {
>> +    nmi_unmasked = (cur_el == target_el) &&
>> +   (((env->cp15.sctlr_el[target_el] & SCTLR_NMI) &&
>> +    (env->allint & PSTATE_ALLINT)) ||
>> +    ((env->cp15.sctlr_el[target_el] &
>> SCTLR_SPINTMASK) &&
>> +    (env->pstate & PSTATE_SP)));
> 
> In the manual, this is "allintmask".  It is easier to follow the logic
> if you use this...

The mannual also require that it must be same EL.

An interrupt is controlled by PSTATE.ALLINT when all of the following apply:
• SCTLR_ELx.NMI is 1.
• The interrupt is targeted at ELx.
• Execution is at ELx.

An interrupt is controlled by PSTATE.SP when all of the following apply:
• SCTLR_ELx.NMI is 1.
• SCTLR_ELx.SPINTMASK is 1.
• The interrupt is targeted at ELx.
• Execution is at ELx.

> 
>> +    nmi_unmasked = !nmi_unmasked;
> 
> ... and not the inverse.
> 
>>   case EXCP_FIQ:
>> -    pstate_unmasked = !(env->daif & PSTATE_F);
>> +    pstate_unmasked = (!(env->daif & PSTATE_F)) & nmi_unmasked;
> 
> Clearer with "&&".
> 
>> +    if (cpu_isar_feature(aa64_nmi, env_archcpu(env))) {
>> +    if (interrupt_request & CPU_INTERRUPT_NMI) {
>> +    excp_idx = EXCP_NMI;
>> +    target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el,
>> secure);
>> +    if (arm_excp_unmasked(cs, excp_idx, target_el,
>> +  cur_el, secure, hcr_el2)) {
>> +    goto found;
>> +    }
>> +    }
>> +    }
> 
> Handling for vNMI?
> 
>> @@ -957,6 +992,7 @@ static void arm_cpu_set_irq(void *opaque, int irq,
>> 

Re: [PATCH v4 19/34] migration/multifd: Allow receiving pages without packets

2024-02-25 Thread Peter Xu
On Tue, Feb 20, 2024 at 07:41:23PM -0300, Fabiano Rosas wrote:
> Currently multifd does not need to have knowledge of pages on the
> receiving side because all the information needed is within the
> packets that come in the stream.
> 
> We're about to add support to fixed-ram migration, which cannot use
> packets because it expects the ramblock section in the migration file
> to contain only the guest pages data.
> 
> Add a data structure to transfer pages between the ram migration code
> and the multifd receiving threads.
> 
> We don't want to reuse MultiFDPages_t for two reasons:
> 
> a) multifd threads don't really need to know about the data they're
>receiving.
> 
> b) the receiving side has to be stopped to load the pages, which means
>we can experiment with larger granularities than page size when
>transferring data.
> 
> Signed-off-by: Fabiano Rosas 
> ---
> @Peter: a 'quit' flag cannot be used instead of pending_job. The
> receiving thread needs know there's no more data coming. If the
> migration thread sets a 'quit' flag, the multifd thread would see the
> flag right away and exit.

Hmm.. isn't this exactly what we want?  I'll comment for this inline below.

> The only way is to clear pending_job on the
> thread and spin once more.
> ---
>  migration/file.c|   1 +
>  migration/multifd.c | 122 +---
>  migration/multifd.h |  15 ++
>  3 files changed, 131 insertions(+), 7 deletions(-)
> 
> diff --git a/migration/file.c b/migration/file.c
> index 5d4975f43e..22d052a71f 100644
> --- a/migration/file.c
> +++ b/migration/file.c
> @@ -6,6 +6,7 @@
>   */
>  
>  #include "qemu/osdep.h"
> +#include "exec/ramblock.h"
>  #include "qemu/cutils.h"
>  #include "qapi/error.h"
>  #include "channel.h"
> diff --git a/migration/multifd.c b/migration/multifd.c
> index 0a5279314d..45a0c7aaa8 100644
> --- a/migration/multifd.c
> +++ b/migration/multifd.c
> @@ -81,9 +81,15 @@ struct {
>  
>  struct {
>  MultiFDRecvParams *params;
> +MultiFDRecvData *data;
>  /* number of created threads */
>  int count;
> -/* syncs main thread and channels */
> +/*
> + * For sockets: this is posted once for each MULTIFD_FLAG_SYNC flag.
> + *
> + * For files: this is only posted at the end of the file load to mark
> + *completion of the load process.
> + */
>  QemuSemaphore sem_sync;
>  /* global number of generated multifd packets */
>  uint64_t packet_num;
> @@ -1110,6 +1116,53 @@ bool multifd_send_setup(void)
>  return true;
>  }
>  
> +bool multifd_recv(void)
> +{
> +int i;
> +static int next_recv_channel;
> +MultiFDRecvParams *p = NULL;
> +MultiFDRecvData *data = multifd_recv_state->data;

[1]

> +
> +/*
> + * next_channel can remain from a previous migration that was
> + * using more channels, so ensure it doesn't overflow if the
> + * limit is lower now.
> + */
> +next_recv_channel %= migrate_multifd_channels();
> +for (i = next_recv_channel;; i = (i + 1) % migrate_multifd_channels()) {
> +if (multifd_recv_should_exit()) {
> +return false;
> +}
> +
> +p = _recv_state->params[i];
> +
> +/*
> + * Safe to read atomically without a lock because the flag is
> + * only set by this function below. Reading an old value of
> + * true is not an issue because it would only send us looking
> + * for the next idle channel.
> + */
> +if (qatomic_read(>pending_job) == false) {
> +next_recv_channel = (i + 1) % migrate_multifd_channels();
> +break;
> +}
> +}

IIUC you'll need an smp_mb_acquire() here.  The ordering of "reading
pending_job" and below must be guaranteed, similar to the sender side.

> +
> +assert(!p->data->size);
> +multifd_recv_state->data = p->data;

[2]

> +p->data = data;
> +
> +qatomic_set(>pending_job, true);

Then here:

   qatomic_store_release(>pending_job, true);

Please consider add comment above all acquire/releases pairs like sender
too.

> +qemu_sem_post(>sem);
> +
> +return true;
> +}
> +
> +MultiFDRecvData *multifd_get_recv_data(void)
> +{
> +return multifd_recv_state->data;
> +}

Can also use it above [1].

I'm thinking maybe we can do something like:

#define  MULTIFD_RECV_DATA_GLOBAL  (multifd_recv_state->data)

Then we can also use it at [2], and replace multifd_get_recv_data()?

> +
>  static void multifd_recv_terminate_threads(Error *err)
>  {
>  int i;
> @@ -1134,11 +1187,26 @@ static void multifd_recv_terminate_threads(Error *err)
>  MultiFDRecvParams *p = _recv_state->params[i];
>  
>  /*
> - * multifd_recv_thread may hung at MULTIFD_FLAG_SYNC handle code,
> - * however try to wakeup it without harm in cleanup phase.
> + * The migration thread and channels interact differently
> + * depending on the presence of packets.
>   

RE: [PATCH rfcv2 07/18] vfio/container: Implement host_iommu_device_init callback in legacy mode

2024-02-25 Thread Duan, Zhenzhong


>-Original Message-
>From: Eric Auger 
>Subject: Re: [PATCH rfcv2 07/18] vfio/container: Implement
>host_iommu_device_init callback in legacy mode
>
>Hi Zhenzhong,
>On 2/1/24 08:28, Zhenzhong Duan wrote:
>> This callback will be used to initialize base and public elements
>> in IOMMULegacyDevice.
>>
>> Signed-off-by: Zhenzhong Duan 
>> ---
>>  hw/vfio/container.c | 7 +++
>>  1 file changed, 7 insertions(+)
>>
>> diff --git a/hw/vfio/container.c b/hw/vfio/container.c
>> index bd25b9fbad..8fafd4b4e5 100644
>> --- a/hw/vfio/container.c
>> +++ b/hw/vfio/container.c
>> @@ -1120,6 +1120,12 @@ out_single:
>>  return ret;
>>  }
>>
>> +static void vfio_legacy_host_iommu_device_init(VFIODevice *vbasedev)
>> +{
>> +host_iommu_base_device_init(>base_hdev, HID_LEGACY,
>> +sizeof(IOMMULegacyDevice));
>To me this should allocate a new
>
> IOMMULegacyDevice and set the VFIODevice base_hdev handle to its base

Sure, will do.

Thanks
Zhenzhong


Re: [PATCH 05/10] hppa: do not require CONFIG_USB

2024-02-25 Thread Thomas Huth

On 24/02/2024 23.38, Paolo Bonzini wrote:

On Fri, Feb 23, 2024 at 8:56 PM BALATON Zoltan  wrote:

-if (!lasi_dev && machine->enable_graphics) {
+if (!lasi_dev && machine->enable_graphics && defaults_enabled()) {


Do we need the defaults_enabled() here? Isn't enable_graphics already
disabled if defaults_enabled() is not set?


Isn't enable_graphics controlled by -nographic and defaults_enabled
controlled by -nodefaults? I think they are independent but maybe that
does not answer the question if it's needed or not.


Indeed they are different. The idea is that if graphics are disabled
you interact with a serial console so you don't need keyboard or
mouse; and if default devices are disabled of course you create as
little as possible and leave everything to the user.


Indeed, I just double-checked and they are independent, sorry for 
mis-remembering that.


 Thomas




RE: [PATCH rfcv2 11/18] intel_iommu: Add set/unset_iommu_device callback

2024-02-25 Thread Duan, Zhenzhong


>-Original Message-
>From: Eric Auger 
>Subject: Re: [PATCH rfcv2 11/18] intel_iommu: Add
>set/unset_iommu_device callback
>
>
>
>On 2/1/24 08:28, Zhenzhong Duan wrote:
>> From: Yi Liu 
>>
>> This adds set/unset_iommu_device() implementation in Intel vIOMMU.
>> In set call, a pointer to host IOMMU device info is stored in hash
>> table indexed by PCI BDF.
>>
>> Signed-off-by: Yi Liu 
>> Signed-off-by: Yi Sun 
>> Signed-off-by: Zhenzhong Duan 
>> ---
>>  hw/i386/intel_iommu_internal.h | 14 +++
>>  include/hw/i386/intel_iommu.h  |  2 +
>>  hw/i386/intel_iommu.c  | 74
>++
>>  3 files changed, 90 insertions(+)
>>
>> diff --git a/hw/i386/intel_iommu_internal.h
>b/hw/i386/intel_iommu_internal.h
>> index f8cf99bddf..3301f54b35 100644
>> --- a/hw/i386/intel_iommu_internal.h
>> +++ b/hw/i386/intel_iommu_internal.h
>> @@ -28,6 +28,8 @@
>>  #ifndef HW_I386_INTEL_IOMMU_INTERNAL_H
>>  #define HW_I386_INTEL_IOMMU_INTERNAL_H
>>  #include "hw/i386/intel_iommu.h"
>> +#include "sysemu/host_iommu_device.h"
>> +#include "hw/vfio/vfio-common.h"
>>
>>  /*
>>   * Intel IOMMU register specification
>> @@ -537,4 +539,16 @@ typedef struct VTDRootEntry VTDRootEntry;
>>  #define VTD_SL_IGN_COM  0xbff0ULL
>>  #define VTD_SL_TM   (1ULL << 62)
>>
>> +
>> +typedef struct VTDHostIOMMUDevice {
>> +IntelIOMMUState *iommu_state;
>> +PCIBus *bus;
>> +uint8_t devfn;
>> +union {
>> +HostIOMMUDevice *dev;
>> +IOMMULegacyDevice *ldev;
>> +IOMMUFDDevice *idev;
>> +};
>again this looks really weird to me. Why don't we simply have
>
>HostIOMMUDevice *dev;

Sure, will do.

Thanks
Zhenzhong



Re: [PATCH v2 0/4] RISC-V: Modularize common match conditions for trigger

2024-02-25 Thread Alistair Francis
On Mon, Feb 26, 2024 at 11:16 AM Alvin Che-Chia Chang(張哲嘉)
 wrote:
>
> Hi Alistair,
>
> > -Original Message-
> > From: Alistair Francis 
> > Sent: Monday, February 26, 2024 8:25 AM
> > To: Alvin Che-Chia Chang(張哲嘉) 
> > Cc: qemu-ri...@nongnu.org; qemu-devel@nongnu.org;
> > alistair.fran...@wdc.com; bin.m...@windriver.com; liwei1...@gmail.com;
> > dbarb...@ventanamicro.com; zhiwei_...@linux.alibaba.com
> > Subject: Re: [PATCH v2 0/4] RISC-V: Modularize common match conditions for
> > trigger
> >
> > [EXTERNAL MAIL 外部信件]
> >
> > On Fri, Feb 23, 2024 at 12:22 PM Alvin Chang via 
> > wrote:
> > >
> > > According to RISC-V Debug specification, the enabled privilege levels
> > > of
> >
> > Can you specify what version of the debug spec?
>
> In general, this series does not add any new functionalities.
> The original implementation has duplicated code in type 2/3/6 triggers.
> I just eliminated those code and modularized them to be 
> trigger_common_match().
> Besides, we may want to check other conditions in the future, so this 
> function can be used for those purposes.

Ah, you are right. I just skimmed the message

>
> When I track the commit history, it seems the code is submitted in the 
> following commits two years ago:
> https://github.com/qemu/qemu/commit/95799e36c15a9ab602a388491c40f6860f6ae8bf
> https://github.com/qemu/qemu/commit/b5f6379d134bd201d52380c73ff73565e6a4321e
> https://github.com/qemu/qemu/commit/c32461d8eeb17490b1b1e969e2ce8f1ecd83bfbb
> https://github.com/qemu/qemu/commit/c472c142a7552f5b0e40378d5643a2810ef1b111
>
> Since they mentioned the "type 6" trigger and "Sdtrig" extension, I assume 
> current implementation is based on Debug Spec version 1.0
> There is no type 6 trigger and Sdtrig extension in Debug Spec version 0.13

Yeah, we are a weird mix-match of the two unfortunately. Which is why
I wanted to be explicit about which debug spec version you are
targeting.

>
> Sincerely,
> Alvin Chang
>
> >
> > Ideally if you can link directly to the PDF that would be very useful.
> > There are multiple versions so it's hard to keep track of.
> >
> > Alistair
> >
> > > the trigger is common match conditions for all the types of the trigger.
> > > This series modularize the code for checking the privilege levels of
> > > type 2/3/6 triggers by implementing functions trigger_common_match()
> > > and trigger_priv_match().
> > >
> > > Additional match conditions, such as CSR tcontrol and textra, can be
> > > further implemented into trigger_common_match() in the future.
> > >
> > > Changes from v1:
> > > - Fix typo
> > > - Add commit description for changing behavior of looping the triggers
> > >   when we check type 2 triggers.
> > >
> > > Alvin Chang (4):
> > >   target/riscv: Add functions for common matching conditions of trigger
> > >   target/riscv: Apply modularized matching conditions for breakpoint
> > >   target/riscv: Apply modularized matching conditions for watchpoint
> > >   target/riscv: Apply modularized matching conditions for icount
> > > trigger
> > >
> > >  target/riscv/debug.c | 124
> > > +--
> > >  1 file changed, 83 insertions(+), 41 deletions(-)
> > >
> > > --
> > > 2.34.1
> > >
> > >
> CONFIDENTIALITY NOTICE:
>
> This e-mail (and its attachments) may contain confidential and legally 
> privileged information or information protected from disclosure. If you are 
> not the intended recipient, you are hereby notified that any disclosure, 
> copying, distribution, or use of the information contained herein is strictly 
> prohibited. In this case, please immediately notify the sender by return 
> e-mail, delete the message (and any accompanying documents) and destroy all 
> printed hard copies. Thank you for your cooperation.
>
> Copyright ANDES TECHNOLOGY CORPORATION - All Rights Reserved.

I'm not sure what you want me to do here

Alistair



Re: [PATCH v2 2/4] scripts/replay-dump.py: Update to current rr record format

2024-02-25 Thread Nicholas Piggin
On Wed Jan 31, 2024 at 7:36 AM AEST, John Snow wrote:
> On Thu, Jan 25, 2024 at 11:09 AM Nicholas Piggin  wrote:
> >
> > The v12 format support for replay-dump has a few issues still. This
> > fixes async decoding; adds event, shutdown, and end decoding; fixes
> > audio in / out events, fixes checkpoint checking of following async
> > events.
> >
> > Signed-off-by: Nicholas Piggin 
> > ---
> >  scripts/replay-dump.py | 132 ++---
> >  1 file changed, 98 insertions(+), 34 deletions(-)
> >
> > diff --git a/scripts/replay-dump.py b/scripts/replay-dump.py
> > index d668193e79..35732da08f 100755
> > --- a/scripts/replay-dump.py
> > +++ b/scripts/replay-dump.py
> > @@ -20,6 +20,7 @@
> >
> >  import argparse
> >  import struct
> > +import os
> >  from collections import namedtuple
> >  from os import path
> >
> > @@ -63,6 +64,10 @@ def read_byte(fin):
> >  "Read a single byte"
> >  return struct.unpack('>B', fin.read(1))[0]
> >
> > +def read_bytes(fin, nr):
> > +"Read a nr bytes"
>
> Existing problem in this file, but please use """triple quotes""" for
> docstrings.

Just coming back to this, sorry, was struggling a bit with ppc merge :/

> > +return fin.read(nr)
> > +
>
> Does it really save a lot of typing to alias fin.read(1) to
> read_bytes(fin, 1) ...?

Not really, I'll squash it.

>
> >  def read_event(fin):
> >  "Read a single byte event, but save some state"
> >  if replay_state.already_read:
> > @@ -134,6 +139,18 @@ def swallow_async_qword(eid, name, dumpfile):
> >  print("  %s(%d) @ %d" % (name, eid, step_id))
> >  return True
> >
> > +def swallow_bytes(eid, name, dumpfile, nr):
> > +"Swallow nr bytes of data without looking at it"
> > +dumpfile.seek(nr, os.SEEK_CUR)
> > +return True
> > +
>
> Why bother returning a bool if it's not based on any condition? Add an
> error check or just drop the return value.
>
> > +def decode_exception(eid, name, dumpfile):
> > +print_event(eid, name)
> > +return True
> > +
>
> I suppose in this case, the return is to fit a common signature.

Yes that's why I did it, but it actually can't fit in the normal
decoder pattern because a nr has to be supplied as well. I'll
change it as you say.

Thanks,
Nick



Re: [PATCH 3/7] scripts/nsis.py: Automatically package required DLLs of QEMU executables

2024-02-25 Thread Stefan Weil via

Am 26.02.24 um 05:35 schrieb Bin Meng:


On Mon, Feb 26, 2024 at 1:37 AM Stefan Weil  wrote:

Am 10.09.22 um 02:37 schrieb Bin Meng:

On Sat, Sep 10, 2022 at 12:49 AM Mark Cave-Ayland
  wrote:

On 08/09/2022 14:28, Bin Meng wrote:


From: Bin Meng

At present packaging the required DLLs of QEMU executables is a
manual process, and error prone.

Actually build/config-host.mak contains a GLIB_BINDIR variable
which is the directory where glib and other DLLs reside. This
works for both Windows native build and cross-build on Linux.
We can use it as the search directory for DLLs and automate
the whole DLL packaging process.

Signed-off-by: Bin Meng
---

meson.build |  1 +
scripts/nsis.py | 46 ++
2 files changed, 43 insertions(+), 4 deletions(-)


[...]>>> diff --git a/scripts/nsis.py b/scripts/nsis.py

index baa6ef9594..03ed7608a2 100644
--- a/scripts/nsis.py
+++ b/scripts/nsis.py
@@ -18,12 +18,36 @@ def signcode(path):
return
subprocess.run([cmd, path])

+def find_deps(exe_or_dll, search_path, analyzed_deps):
+deps = [exe_or_dll]
+output = subprocess.check_output(["objdump", "-p", exe_or_dll], text=True)

This fails on non x86 hosts where objdump does not know how to handle a
Windows x86_64 exe file.

Does this command work in the MSYS2 environment on Windows Arm?



I don't know and cannot test that, because I don't run Windows on ARM.


+output = output.split("\n")
+for line in output:
+if not line.startswith("\tDLL Name: "):
+continue
+
+dep = line.split("DLL Name: ")[1].strip()
+if dep in analyzed_deps:
+continue
+
+dll = os.path.join(search_path, dep)
+if not os.path.exists(dll):
+# assume it's a Windows provided dll, skip it
+continue
+
+analyzed_deps.add(dep)
+# locate the dll dependencies recursively
+rdeps = find_deps(dll, search_path, analyzed_deps)
+deps.extend(rdeps)
+
+return deps

[...]

FWIW I wrote a similar script a while back to help package a custom Windows 
build for
a client, however I used ldd instead of objdump since it provided the full 
paths for
DLLs installed in the msys2/mingw-w64 environment via pacman which were outside 
the
QEMU build tree.


Yep, ldd also works, but only on Windows native build. objdump can
work on both Windows native and Linux cross builds.


objdump fails on Linux cross builds on any non x86 host, because objdump
typically only supports the native host architecture.

Therefore I get an error on an ARM64 host (podman on Mac M1):

  objdump: /tmp/tmpvae5u0qm/qemu/qemu-system-aarch64.exe: file
format not recognized

I could use x86_64-w64-mingw32-objdump to fix the cross builds, but then
native builds might fail because they don't have x86_64-w64-mingw32-objdump.

Is there a simple way how we can get the information here whether
objdump requires a cross build prefix?

For QEMU Windows, I believe the only supported architecture is x86_64,
correct? Do we want to support (cross) building QEMU for Windows Arm?



Yes, I think we only support QEMU on Windows x86_64. I also don't know 
anyone who has tried building for Windows ARM. And up to now I also was 
never asked for that, so obviously there is still no need for it.




Based on your observation, objdump on Linux cross builds on any x86
host works, but not on non x86 host.
Maybe it's a hint to ask for binutils guys to include the PE format
support for objdump Arm by default.



I am afraid that we'll have to find a solution on the QEMU side, not 
wait until all binutils support the PE format for x86_64 (which would 
make the binaries or the library much larger).


Stefan



RE: [PATCH rfcv2 10/18] hw/pci: Introduce pci_device_set/unset_iommu_device()

2024-02-25 Thread Duan, Zhenzhong


>-Original Message-
>From: Eric Auger 
>Subject: Re: [PATCH rfcv2 10/18] hw/pci: Introduce
>pci_device_set/unset_iommu_device()
>
>Hi Zhenzhong,
>
>On 2/1/24 08:28, Zhenzhong Duan wrote:
>> From: Yi Liu 
>>
>> This adds pci_device_set/unset_iommu_device() to set/unset
>> HostIOMMUDevice for a given PCIe device. Caller of set
>> should fail if set operation fails.
>>
>> Extract out pci_device_get_iommu_bus_devfn() to facilitate
>> implementation of pci_device_set/unset_iommu_device().
>>
>> Signed-off-by: Yi Liu 
>> Signed-off-by: Yi Sun 
>> Signed-off-by: Nicolin Chen 
>> Signed-off-by: Zhenzhong Duan 
>> ---
>>  include/hw/pci/pci.h | 38 ++-
>>  hw/pci/pci.c | 62
>+---
>>  2 files changed, 96 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
>> index fa6313aabc..5b471fd380 100644
>> --- a/include/hw/pci/pci.h
>> +++ b/include/hw/pci/pci.h
>> @@ -3,6 +3,7 @@
>>
>>  #include "exec/memory.h"
>>  #include "sysemu/dma.h"
>> +#include "sysemu/host_iommu_device.h"
>>
>>  /* PCI includes legacy ISA access.  */
>>  #include "hw/isa/isa.h"
>> @@ -384,10 +385,45 @@ typedef struct PCIIOMMUOps {
>>   *
>>   * @devfn: device and function number
>>   */
>> -   AddressSpace * (*get_address_space)(PCIBus *bus, void *opaque, int
>devfn);
>> +AddressSpace * (*get_address_space)(PCIBus *bus, void *opaque, int
>devfn);
>> +/**
>> + * @set_iommu_device: set iommufd device for a PCI device to
>vIOMMU
>attach a HostIOMMUDevice to a vIOMMU

Will do.

>> + *
>> + * Optional callback, if not implemented in vIOMMU, then vIOMMU
>can't
>> + * utilize iommufd specific features.
>looks too iommufd specific. Then vIOMMU can't retrieve host information
>from the associated HostIOMMUDevice

Will do.

>> + *
>> + * Return true if iommufd device is accepted, or else return false with
>s/accepted/attached

Will do.

>> + * errp set.
>> + *
>> + * @bus: the #PCIBus of the PCI device.
>> + *
>> + * @opaque: the data passed to pci_setup_iommu().
>> + *
>> + * @devfn: device and function number of the PCI device.
>> + *
>> + * @dev: the data structure representing host assigned device.
>> + *
>> + */
>> +int (*set_iommu_device)(PCIBus *bus, void *opaque, int devfn,
>> +HostIOMMUDevice *dev, Error **errp);
>> +/**
>> + * @unset_iommu_device: unset iommufd device for a PCI device from
>vIOMMU
>same suggestion here

Will do.

Thanks
Zhenzhong


Re: [PATCH v2 1/3] hw/arm/sbsa-ref: Do not open-code ahci_ide_create_devs()

2024-02-25 Thread Thomas Huth

On 25/02/2024 18.21, Philippe Mathieu-Daudé wrote:

On 25/2/24 18:16, Philippe Mathieu-Daudé wrote:

Use ahci_ide_create_devs() instead of open-coding it.
Not accessing AHCIDevice internals anymore allows to
remove "hw/ide/ahci_internal.h" (which isn't really a
public header).

Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/arm/sbsa-ref.c | 9 +
  1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index 5d3a574664..995c7be23e 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -37,7 +37,6 @@
  #include "hw/block/flash.h"
  #include "hw/boards.h"
  #include "hw/ide/internal.h"
-#include "hw/ide/ahci_internal.h"
  #include "hw/ide/ahci-sysbus.h"
  #include "hw/intc/arm_gicv3_common.h"
  #include "hw/intc/arm_gicv3_its_common.h"
@@ -572,7 +571,6 @@ static void create_ahci(const SBSAMachineState *sms)
  DriveInfo *hd[NUM_SATA_PORTS];
  SysbusAHCIState *sysahci;
  AHCIState *ahci;
-    int i;
  dev = qdev_new("sysbus-ahci");
  qdev_prop_set_uint32(dev, "num-ports", NUM_SATA_PORTS);
@@ -583,12 +581,7 @@ static void create_ahci(const SBSAMachineState *sms)
  sysahci = SYSBUS_AHCI(dev);
  ahci = >ahci;


Bah, we can even remove that 'ahci' variable.


  ide_drive_get(hd, ARRAY_SIZE(hd));
-    for (i = 0; i < ahci->ports; i++) {
-    if (hd[i] == NULL) {
-    continue;
-    }
-    ide_bus_create_drive(>dev[i].port, 0, hd[i]);
-    }
+    ahci_ide_create_devs(ahci, hd);
  }


-- >8 --
@@ -571,8 +570,6 @@ static void create_ahci(const SBSAMachineState *sms)
  DeviceState *dev;
  DriveInfo *hd[NUM_SATA_PORTS];
  SysbusAHCIState *sysahci;
-    AHCIState *ahci;
-    int i;

  dev = qdev_new("sysbus-ahci");
  qdev_prop_set_uint32(dev, "num-ports", NUM_SATA_PORTS);
@@ -581,14 +578,8 @@ static void create_ahci(const SBSAMachineState *sms)
  sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(sms->gic, 
irq));


  sysahci = SYSBUS_AHCI(dev);
-    ahci = >ahci;
  ide_drive_get(hd, ARRAY_SIZE(hd));
-    for (i = 0; i < ahci->ports; i++) {
-    if (hd[i] == NULL) {
-    continue;
-    }
-    ide_bus_create_drive(>dev[i].port, 0, hd[i]);
-    }
+    ahci_ide_create_devs(>ahci, hd);
  }


Reviewed-by: Thomas Huth 





RE: [PATCH rfcv2 04/18] vfio: Add host iommu device instance into VFIODevice

2024-02-25 Thread Duan, Zhenzhong
Hi Eric,

>-Original Message-
>From: Eric Auger 
>Subject: Re: [PATCH rfcv2 04/18] vfio: Add host iommu device instance into
>VFIODevice
>
>
>
>On 2/1/24 08:28, Zhenzhong Duan wrote:
>> Either IOMMULegacyDevice or IOMMUFDDevice into VFIODevice, neither
>> both.
>>
>> Signed-off-by: Zhenzhong Duan 
>> ---
>>  include/hw/vfio/vfio-common.h | 11 +++
>>  1 file changed, 11 insertions(+)
>>
>> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-
>common.h
>> index 8bfb9cbe94..1bbad003ee 100644
>> --- a/include/hw/vfio/vfio-common.h
>> +++ b/include/hw/vfio/vfio-common.h
>> @@ -32,6 +32,7 @@
>>  #include "sysemu/sysemu.h"
>>  #include "hw/vfio/vfio-container-base.h"
>>  #include "sysemu/host_iommu_device.h"
>> +#include "sysemu/iommufd.h"
>>
>>  #define VFIO_MSG_PREFIX "vfio %s: "
>>
>> @@ -132,8 +133,18 @@ typedef struct VFIODevice {
>>  bool dirty_tracking;
>>  int devid;
>>  IOMMUFDBackend *iommufd;
>> +union {
>> +HostIOMMUDevice base_hdev;
>> +IOMMULegacyDevice legacy_dev;
>> +IOMMUFDDevice iommufd_dev;
>I think you should rather have a HostIOMMUDevice handle.
>
>host_iommu_device_init cb would allocate the right type of the derived
>object and you would store the base object pointer here.

Sorry for late response, just back from vacation.

I didn't use a HostIOMMUDevice handle but a statically allocated one
Because in following patch:

'[PATCH rfcv2 05/18] vfio: Remove redundant iommufd and devid elements in 
VFIODevice'

iommufd and devid are removed from VFIODevice. I need a place to store
them early in attachment. The handle is dynamically allocated after
attachment and can't be used for that purpose.

I'll change to use HostIOMMUDevice handle and drop patch5 in rfcv3,
Let me know if you have other comments.

Thanks
Zhenzhong


Re: [PATCH v4 00/34] migration: File based migration with multifd and fixed-ram

2024-02-25 Thread Peter Xu
On Tue, Feb 20, 2024 at 07:41:04PM -0300, Fabiano Rosas wrote:
> 0) Cleanups   [1-5]

While I am still reading the rest.. I queued these five first.

-- 
Peter Xu




Re: [PATCH v2 4/6] hw/i386/pc: Remove unneeded class attribute "kvmclock_enabled"

2024-02-25 Thread Thomas Huth

On 24/02/2024 14.58, Bernhard Beschow wrote:

PCMachineClass introduces the attribute into the class hierarchy and sets it to
true. There is no sub class overriding the attribute. Commit 30d2a17b46e9
"hw/i386: Remove the deprecated machines 0.12 up to 0.15" removed the last
overrides of this attribute. The attribute is now unneeded and can be removed.

Fixes: 30d2a17b46e9 "hw/i386: Remove the deprecated machines 0.12 up to 0.15"
Cc: Thomas Huth 
Signed-off-by: Bernhard Beschow 
---
  include/hw/i386/pc.h | 1 -
  hw/i386/pc.c | 1 -
  hw/i386/pc_piix.c| 2 +-
  3 files changed, 1 insertion(+), 3 deletions(-)


Reviewed-by: Thomas Huth 




Re: [PATCH v4 18/34] migration/multifd: Allow multifd without packets

2024-02-25 Thread Peter Xu
On Tue, Feb 20, 2024 at 07:41:22PM -0300, Fabiano Rosas wrote:
> For the upcoming support to the new 'fixed-ram' migration stream
> format, we cannot use multifd packets because each write into the
> ramblock section in the migration file is expected to contain only the
> guest pages. They are written at their respective offsets relative to
> the ramblock section header.
> 
> There is no space for the packet information and the expected gains
> from the new approach come partly from being able to write the pages
> sequentially without extraneous data in between.
> 
> The new format also simply doesn't need the packets and all necessary
> information can be taken from the standard migration headers with some
> (future) changes to multifd code.
> 
> Use the presence of the fixed-ram capability to decide whether to send
> packets.
> 
> This only moves code under multifd_use_packets(), it has no effect for
> now as fixed-ram cannot yet be enabled with multifd.
> 
> Signed-off-by: Fabiano Rosas 

Mostly good to me, but since we'll probably need at least one more round, I
left some more comments.

> ---
>  migration/multifd.c | 188 +++-
>  1 file changed, 117 insertions(+), 71 deletions(-)
> 
> diff --git a/migration/multifd.c b/migration/multifd.c
> index 5a38cb222f..0a5279314d 100644
> --- a/migration/multifd.c
> +++ b/migration/multifd.c
> @@ -92,6 +92,11 @@ struct {
>  MultiFDMethods *ops;
>  } *multifd_recv_state;
>  
> +static bool multifd_use_packets(void)
> +{
> +return !migrate_fixed_ram();
> +}
> +
>  /* Multifd without compression */
>  
>  /**
> @@ -136,10 +141,11 @@ static void nocomp_send_cleanup(MultiFDSendParams *p, 
> Error **errp)
>  static int nocomp_send_prepare(MultiFDSendParams *p, Error **errp)
>  {
>  bool use_zero_copy_send = migrate_zero_copy_send();
> +bool use_packets = multifd_use_packets();
>  MultiFDPages_t *pages = p->pages;
>  int ret;
>  
> -if (!use_zero_copy_send) {
> +if (!use_zero_copy_send && use_packets) {
>  /*
>   * Only !zerocopy needs the header in IOV; zerocopy will
>   * send it separately.
> @@ -156,14 +162,16 @@ static int nocomp_send_prepare(MultiFDSendParams *p, 
> Error **errp)
>  p->next_packet_size = pages->num * p->page_size;
>  p->flags |= MULTIFD_FLAG_NOCOMP;

These two shouldn't be needed by fixed-ram, either?

IIUC only the IOV prepare and future zero page detections may be needed for
fixed-ram in nocomp_send_prepare(). Perhaps something like this would be
clearer?

static void nocomp_send_prepare_iovs(MultiFDSendParams *p)
{
MultiFDPages_t *pages = p->pages;
int i;

for (i = 0; i < pages->num; i++) {
p->iov[p->iovs_num].iov_base = pages->block->host + pages->offset[i];
p->iov[p->iovs_num].iov_len = p->page_size;
p->iovs_num++;
}
}

static int nocomp_send_prepare(MultiFDSendParams *p, Error **errp)
{
bool use_zero_copy_send = migrate_zero_copy_send();
MultiFDPages_t *pages = p->pages;
int ret;

if (!multifd_use_packet()) {
nocomp_send_prepare_iovs(p);
return true;
}

if (!use_zero_copy_send) {
/*
 * Only !zerocopy needs the header in IOV; zerocopy will
 * send it separately.
 */
multifd_send_prepare_header(p);
}

nocomp_send_prepare_iovs(p);
...
}

Then in the future we can also put zero page detection logic into this new
nocomp_send_prepare_iovs(), iiuc.

>  
> -multifd_send_fill_packet(p);
> +if (use_packets) {
> +multifd_send_fill_packet(p);
>  
> -if (use_zero_copy_send) {
> -/* Send header first, without zerocopy */
> -ret = qio_channel_write_all(p->c, (void *)p->packet,
> -p->packet_len, errp);
> -if (ret != 0) {
> -return -1;
> +if (use_zero_copy_send) {
> +/* Send header first, without zerocopy */
> +ret = qio_channel_write_all(p->c, (void *)p->packet,
> +p->packet_len, errp);
> +if (ret != 0) {
> +return -1;
> +}
>  }
>  }
>  
> @@ -215,11 +223,16 @@ static int nocomp_recv(MultiFDRecvParams *p, Error 
> **errp)
> p->id, flags, MULTIFD_FLAG_NOCOMP);
>  return -1;
>  }
> -for (int i = 0; i < p->normal_num; i++) {
> -p->iov[i].iov_base = p->host + p->normal[i];
> -p->iov[i].iov_len = p->page_size;
> +
> +if (multifd_use_packets()) {
> +for (int i = 0; i < p->normal_num; i++) {
> +p->iov[i].iov_base = p->host + p->normal[i];
> +p->iov[i].iov_len = p->page_size;
> +}
> +return qio_channel_readv_all(p->c, p->iov, p->normal_num, errp);
>  }
> -return qio_channel_readv_all(p->c, p->iov, p->normal_num, errp);
> +
> +return 0;
>  }
>  
>  static MultiFDMethods multifd_nocomp_ops = {
> @@ -799,15 

Re: [PATCH v4 14/34] migration/ram: Add incoming 'fixed-ram' migration

2024-02-25 Thread Peter Xu
On Tue, Feb 20, 2024 at 07:41:18PM -0300, Fabiano Rosas wrote:
> Add the necessary code to parse the format changes for the 'fixed-ram'
> capability.
> 
> One of the more notable changes in behavior is that in the 'fixed-ram'
> case ram pages are restored in one go rather than constantly looping
> through the migration stream.
> 
> Signed-off-by: Nikolay Borisov 
> Signed-off-by: Fabiano Rosas 

Reviewed-by: Peter Xu 

Two more nitpicks below.

> ---
> - added error propagation for read_ramblock_fixed_ram()
> - removed buf_size variable
> ---
>  migration/ram.c | 142 
>  1 file changed, 142 insertions(+)
> 
> diff --git a/migration/ram.c b/migration/ram.c
> index 84c531722c..5932e1b8e1 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -106,6 +106,12 @@
>   */
>  #define FIXED_RAM_FILE_OFFSET_ALIGNMENT 0x10
>  
> +/*
> + * When doing fixed-ram migration, this is the amount we read from the
> + * pages region in the migration file at a time.
> + */
> +#define FIXED_RAM_LOAD_BUF_SIZE 0x10
> +
>  XBZRLECacheStats xbzrle_counters;
>  
>  /* used by the search for pages to send */
> @@ -2999,6 +3005,35 @@ static void fixed_ram_setup_ramblock(QEMUFile *file, 
> RAMBlock *block)
>  qemu_set_offset(file, block->pages_offset + block->used_length, 
> SEEK_SET);
>  }
>  
> +static bool fixed_ram_read_header(QEMUFile *file, FixedRamHeader *header,
> +  Error **errp)
> +{
> +size_t ret, header_size = sizeof(FixedRamHeader);
> +
> +ret = qemu_get_buffer(file, (uint8_t *)header, header_size);
> +if (ret != header_size) {
> +error_setg(errp, "Could not read whole fixed-ram migration header "
> +   "(expected %zd, got %zd bytes)", header_size, ret);
> +return false;
> +}
> +
> +/* migration stream is big-endian */
> +header->version = be32_to_cpu(header->version);
> +
> +if (header->version > FIXED_RAM_HDR_VERSION) {
> +error_setg(errp, "Migration fixed-ram capability version mismatch "
> +   "(expected %d, got %d)", FIXED_RAM_HDR_VERSION,
> +   header->version);

Instead of "mismatch", perhaps "not supported"?

It doesn't need to strictly match the macro defined, e.g., if we boost it
some day we could support more than one versions?  However larger than the
macro means it came from a newer QEMU, hence not supported seems more
appropriate.

> +return false;
> +}
> +
> +header->page_size = be64_to_cpu(header->page_size);
> +header->bitmap_offset = be64_to_cpu(header->bitmap_offset);
> +header->pages_offset = be64_to_cpu(header->pages_offset);
> +
> +return true;
> +}
> +
>  /*
>   * Each of ram_save_setup, ram_save_iterate and ram_save_complete has
>   * long-running RCU critical section.  When rcu-reclaims in the code
> @@ -3900,6 +3935,102 @@ void colo_flush_ram_cache(void)
>  trace_colo_flush_ram_cache_end();
>  }
>  
> +static bool read_ramblock_fixed_ram(QEMUFile *f, RAMBlock *block,
> +long num_pages, unsigned long *bitmap,
> +Error **errp)
> +{
> +ERRP_GUARD();
> +unsigned long set_bit_idx, clear_bit_idx;
> +ram_addr_t offset;
> +void *host;
> +size_t read, unread, size;
> +
> +for (set_bit_idx = find_first_bit(bitmap, num_pages);
> + set_bit_idx < num_pages;
> + set_bit_idx = find_next_bit(bitmap, num_pages, clear_bit_idx + 1)) {
> +
> +clear_bit_idx = find_next_zero_bit(bitmap, num_pages, set_bit_idx + 
> 1);
> +
> +unread = TARGET_PAGE_SIZE * (clear_bit_idx - set_bit_idx);
> +offset = set_bit_idx << TARGET_PAGE_BITS;
> +
> +while (unread > 0) {
> +host = host_from_ram_block_offset(block, offset);
> +if (!host) {
> +error_setg(errp, "page outside of ramblock %s range",
> +   block->idstr);
> +return false;
> +}
> +
> +size = MIN(unread, FIXED_RAM_LOAD_BUF_SIZE);
> +
> +read = qemu_get_buffer_at(f, host, size,
> +  block->pages_offset + offset);
> +if (!read) {
> +goto err;
> +}
> +offset += read;
> +unread -= read;
> +}
> +}
> +
> +return true;
> +
> +err:
> +qemu_file_get_error_obj(f, errp);
> +error_prepend(errp, "(%s) failed to read page " RAM_ADDR_FMT
> +  "from file offset %" PRIx64 ": ", block->idstr, offset,
> +  block->pages_offset + offset);
> +return false;
> +}
> +
> +static void parse_ramblock_fixed_ram(QEMUFile *f, RAMBlock *block,
> + ram_addr_t length, Error **errp)
> +{
> +g_autofree unsigned long *bitmap = NULL;
> +FixedRamHeader header;
> +size_t bitmap_size;
> +long num_pages;
> +
> +if 

Re: [PATCH v2] virtio-pci: correctly set virtio pci queue mem multiplier

2024-02-25 Thread Jason Wang
On Tue, Feb 20, 2024 at 3:41 PM Michael S. Tsirkin  wrote:
>
> On Tue, Feb 20, 2024 at 12:39:35PM +0530, Srujana Challa wrote:
> > Currently, virtio_pci_queue_mem_mult function always returns 4K
> > when VIRTIO_PCI_FLAG_PAGE_PER_VQ is set. But this won't
> > work for vhost vdpa when host has page size other than 4K.
> > This patch introduces a new property(page-per-vdpa-vq) for vdpa
> > use case to fix the same.
> >
> > Signed-off-by: Srujana Challa 
> > ---
> > v1->v2:
> > - Introduced a new property to get virtqueue mem multiplier for
> >   vdpa use case.
>
>
> OK, I would maybe call it host-page-per-vq?
>
> Jason?
>

I agree.

Thanks

> >  hw/virtio/virtio-pci.c | 10 --
> >  include/hw/virtio/virtio-pci.h |  5 +
> >  2 files changed, 13 insertions(+), 2 deletions(-)
> >
> > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> > index 1a7039fb0c..28dd6ab8b5 100644
> > --- a/hw/virtio/virtio-pci.c
> > +++ b/hw/virtio/virtio-pci.c
> > @@ -320,8 +320,12 @@ static bool virtio_pci_ioeventfd_enabled(DeviceState 
> > *d)
> >
> >  static inline int virtio_pci_queue_mem_mult(struct VirtIOPCIProxy *proxy)
> >  {
> > -return (proxy->flags & VIRTIO_PCI_FLAG_PAGE_PER_VQ) ?
> > -QEMU_VIRTIO_PCI_QUEUE_MEM_MULT : 4;
> > +if (proxy->flags & VIRTIO_PCI_FLAG_PAGE_PER_VQ)
> > +return QEMU_VIRTIO_PCI_QUEUE_MEM_MULT;
> > +else if (proxy->flags & VIRTIO_PCI_FLAG_PAGE_PER_VDPA_VQ)
> > +return qemu_real_host_page_size();
> > +else
> > +return 4;
> >  }
> >
> >  static int virtio_pci_ioeventfd_assign(DeviceState *d, EventNotifier 
> > *notifier,
> > @@ -2301,6 +2305,8 @@ static Property virtio_pci_properties[] = {
> >  VIRTIO_PCI_FLAG_INIT_FLR_BIT, true),
> >  DEFINE_PROP_BIT("aer", VirtIOPCIProxy, flags,
> >  VIRTIO_PCI_FLAG_AER_BIT, false),
> > +DEFINE_PROP_BIT("page-per-vdpa-vq", VirtIOPCIProxy, flags,
> > +VIRTIO_PCI_FLAG_PAGE_PER_VDPA_VQ_BIT, false),
> >  DEFINE_PROP_END_OF_LIST(),
> >  };
> >
> > diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h
> > index 59d88018c1..10a30c26a2 100644
> > --- a/include/hw/virtio/virtio-pci.h
> > +++ b/include/hw/virtio/virtio-pci.h
> > @@ -43,6 +43,7 @@ enum {
> >  VIRTIO_PCI_FLAG_INIT_FLR_BIT,
> >  VIRTIO_PCI_FLAG_AER_BIT,
> >  VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED_BIT,
> > +VIRTIO_PCI_FLAG_PAGE_PER_VDPA_VQ_BIT,
> >  };
> >
> >  /* Need to activate work-arounds for buggy guests at vmstate load. */
> > @@ -89,6 +90,10 @@ enum {
> >  #define VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED \
> >(1 << VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED_BIT)
> >
> > +/* page per vdpa vq flag to be used for vhost vdpa backends */
> > +#define VIRTIO_PCI_FLAG_PAGE_PER_VDPA_VQ \
> > +(1 << VIRTIO_PCI_FLAG_PAGE_PER_VDPA_VQ_BIT)
> > +
> >  typedef struct {
> >  MSIMessage msg;
> >  int virq;
> > --
> > 2.25.1
>




Re: [PATCH 3/7] scripts/nsis.py: Automatically package required DLLs of QEMU executables

2024-02-25 Thread Bin Meng
On Mon, Feb 26, 2024 at 1:37 AM Stefan Weil  wrote:
>
> Am 10.09.22 um 02:37 schrieb Bin Meng:
> > On Sat, Sep 10, 2022 at 12:49 AM Mark Cave-Ayland
> >  wrote:
> >>
> >> On 08/09/2022 14:28, Bin Meng wrote:
> >>
> >>> From: Bin Meng 
> >>>
> >>> At present packaging the required DLLs of QEMU executables is a
> >>> manual process, and error prone.
> >>>
> >>> Actually build/config-host.mak contains a GLIB_BINDIR variable
> >>> which is the directory where glib and other DLLs reside. This
> >>> works for both Windows native build and cross-build on Linux.
> >>> We can use it as the search directory for DLLs and automate
> >>> the whole DLL packaging process.
> >>>
> >>> Signed-off-by: Bin Meng 
> >>> ---
> >>>
> >>>meson.build |  1 +
> >>>scripts/nsis.py | 46 ++
> >>>2 files changed, 43 insertions(+), 4 deletions(-)
> >>>
> [...]>>> diff --git a/scripts/nsis.py b/scripts/nsis.py
> >>> index baa6ef9594..03ed7608a2 100644
> >>> --- a/scripts/nsis.py
> >>> +++ b/scripts/nsis.py
> >>> @@ -18,12 +18,36 @@ def signcode(path):
> >>>return
> >>>subprocess.run([cmd, path])
> >>>
> >>> +def find_deps(exe_or_dll, search_path, analyzed_deps):
> >>> +deps = [exe_or_dll]
> >>> +output = subprocess.check_output(["objdump", "-p", exe_or_dll], 
> >>> text=True)
>
> This fails on non x86 hosts where objdump does not know how to handle a
> Windows x86_64 exe file.

Does this command work in the MSYS2 environment on Windows Arm?

>
> >>> +output = output.split("\n")
> >>> +for line in output:
> >>> +if not line.startswith("\tDLL Name: "):
> >>> +continue
> >>> +
> >>> +dep = line.split("DLL Name: ")[1].strip()
> >>> +if dep in analyzed_deps:
> >>> +continue
> >>> +
> >>> +dll = os.path.join(search_path, dep)
> >>> +if not os.path.exists(dll):
> >>> +# assume it's a Windows provided dll, skip it
> >>> +continue
> >>> +
> >>> +analyzed_deps.add(dep)
> >>> +# locate the dll dependencies recursively
> >>> +rdeps = find_deps(dll, search_path, analyzed_deps)
> >>> +deps.extend(rdeps)
> >>> +
> >>> +return deps
> [...]
> >>
> >> FWIW I wrote a similar script a while back to help package a custom 
> >> Windows build for
> >> a client, however I used ldd instead of objdump since it provided the full 
> >> paths for
> >> DLLs installed in the msys2/mingw-w64 environment via pacman which were 
> >> outside the
> >> QEMU build tree.
> >>
> >
> > Yep, ldd also works, but only on Windows native build. objdump can
> > work on both Windows native and Linux cross builds.
>
>
> objdump fails on Linux cross builds on any non x86 host, because objdump
> typically only supports the native host architecture.
>
> Therefore I get an error on an ARM64 host (podman on Mac M1):
>
>  objdump: /tmp/tmpvae5u0qm/qemu/qemu-system-aarch64.exe: file
> format not recognized
>
> I could use x86_64-w64-mingw32-objdump to fix the cross builds, but then
> native builds might fail because they don't have x86_64-w64-mingw32-objdump.
>
> Is there a simple way how we can get the information here whether
> objdump requires a cross build prefix?

For QEMU Windows, I believe the only supported architecture is x86_64,
correct? Do we want to support (cross) building QEMU for Windows Arm?

Based on your observation, objdump on Linux cross builds on any x86
host works, but not on non x86 host.
Maybe it's a hint to ask for binutils guys to include the PE format
support for objdump Arm by default.

Regards,
Bin



Re: [PATCH v4 13/34] migration/ram: Add outgoing 'fixed-ram' migration

2024-02-25 Thread Peter Xu
On Tue, Feb 20, 2024 at 07:41:17PM -0300, Fabiano Rosas wrote:
> Implement the outgoing migration side for the 'fixed-ram' capability.
> 
> A bitmap is introduced to track which pages have been written in the
> migration file. Pages are written at a fixed location for every
> ramblock. Zero pages are ignored as they'd be zero in the destination
> migration as well.
> 
> The migration stream is altered to put the dirty pages for a ramblock
> after its header instead of having a sequential stream of pages that
> follow the ramblock headers.
> 
> Without fixed-ram (current):With fixed-ram (new):
> 
>  -   
>  | ramblock 1 header |   | ramblock 1 header|
>  -   
>  | ramblock 2 header |   | ramblock 1 fixed-ram header  |
>  -   
>  | ...   |   | padding to next 1MB boundary |
>  -   | ...  |
>  | ramblock n header |   
>  -   | ramblock 1 pages |
>  | RAM_SAVE_FLAG_EOS |   | ...  |
>  -   
>  | stream of pages   |   | ramblock 2 header|
>  | (iter 1)  |   
>  | ...   |   | ramblock 2 fixed-ram header  |
>  -   
>  | RAM_SAVE_FLAG_EOS |   | padding to next 1MB boundary |
>  -   | ...  |
>  | stream of pages   |   
>  | (iter 2)  |   | ramblock 2 pages |
>  | ...   |   | ...  |
>  -   
>  | ...   |   | ...  |
>  -   
>  | RAM_SAVE_FLAG_EOS|
>  
>  | ...  |
>  
> 
> where:
>  - ramblock header: the generic information for a ramblock, such as
>idstr, used_len, etc.
> 
>  - ramblock fixed-ram header: the new information added by this
>feature: bitmap of pages written, bitmap size and offset of pages
>in the migration file.
> 
> Signed-off-by: Nikolay Borisov 
> Signed-off-by: Fabiano Rosas 

Reviewed-by: Peter Xu 

Still one comment below:

[...]

> @@ -3187,6 +3288,18 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
>  return ret;
>  }
>  
> +if (migrate_fixed_ram()) {
> +ram_save_file_bmap(f);
> +
> +if (qemu_file_get_error(f)) {
> +Error *local_err = NULL;
> +int err = qemu_file_get_error_obj(f, _err);
> +
> +error_reportf_err(local_err, "Failed to write bitmap to file: ");

We always do error report if we set s->error.

Ideally I think we should have Error** passed to the caller and set
s->error there, instead of report here.  But the whole error handling is
still a bit of a mess, so I guess we can do anything on top.

> +return -err;
> +}
> +}

-- 
Peter Xu




Re: [PATCH] migration: Free argv

2024-02-25 Thread Peter Xu
On Sun, Feb 25, 2024 at 02:54:01PM +0900, Akihiko Odaki wrote:
> exec_start_outgoing_migration() and exec_start_incoming_migration()
> leak argv because it uses g_steal_pointer() is used to pass argv
> qio_channel_command_new_spawn() while it does not free argv either.
> 
> Removing g_steal_pointer() is not sufficient though because argv is
> typed g_auto(GStrv), which means the array of strings *and strings* will
> be freed. The strings are only borrowed from the caller of
> exec_start_outgoing_migration() and exec_start_incoming_migration() so
> freeing them result in double-free.
> 
> Instead, type argv as g_autofree char **. This ensures only the array
> of strings will be freed and the strings won't be freed. Also, remove
> unnecessary casts according to the new type.
> 
> Fixes: cbab4face57b ("migration: convert exec backend to accept 
> MigrateAddress.")
> Signed-off-by: Akihiko Odaki 

Cc: qemu-stable 
Reviewed-by: Peter Xu 

This should conflict with Steve's other series:

https://lore.kernel.org/r/1708638470-114846-1-git-send-email-steven.sist...@oracle.com

Considering this can be stable material, should be easier if we have the
other series rebased on top of this, even if that was sent first..

Steve, do you still plan to repost your series?  Maybe you can review it &
pick this up into your series?  Then whoever pick up your series will pick
up both (Markus will?)?

Thanks,

-- 
Peter Xu




Re: [PATCH v2 0/5] migration: cleanup TLS channel referencing

2024-02-25 Thread Peter Xu
On Thu, Feb 22, 2024 at 05:52:56PM +0800, pet...@redhat.com wrote:
> From: Peter Xu 
> 
> v2:
> - add patches
>   - migration/multifd: Make multifd_channel_connect() return void
>   - migration/multifd: Cleanup outgoing_args in state destroy
>   - migration/multifd: Drop unnecessary helper to destroy IOC
> - fix spelling
> 
> This is a small cleanup patchset to firstly cleanup tls iochannel deref on
> error paths, then further remove one unused var on yank if the cleanup
> applies.  In v2 three more small cleanups on top as suggested by reviewers.
> 
> Please feel free to have a look, thanks.
> 
> Peter Xu (5):
>   migration/multifd: Cleanup TLS iochannel referencing
>   migration/multifd: Drop registered_yank
>   migration/multifd: Make multifd_channel_connect() return void
>   migration/multifd: Cleanup outgoing_args in state destroy
>   migration/multifd: Drop unnecessary helper to destroy IOC

queued.

-- 
Peter Xu




Re: [PATCH v4 11/34] migration/ram: Introduce 'fixed-ram' migration capability

2024-02-25 Thread Peter Xu
On Tue, Feb 20, 2024 at 07:41:15PM -0300, Fabiano Rosas wrote:
> + Without fixed-ram:  With fixed-ram:
> +
> + -   
> + | ramblock 1 header |   | ramblock 1 header|
> + -   
> + | ramblock 2 header |   | ramblock 1 fixed-ram header  |
> + -   
> + | ...   |   | padding to next 1MB boundary |
> + -   | ...  |
> + | ramblock n header |   
> + -   | ramblock 1 pages |
> + | RAM_SAVE_FLAG_EOS |   | ...  |
> + -   
> + | stream of pages   |   | ramblock 2 header|
> + | (iter 1)  |   
> + | ...   |   | ramblock 2 fixed-ram header  |
> + -   
> + | RAM_SAVE_FLAG_EOS |   | padding to next 1MB boundary |
> + -   | ...  |
> + | stream of pages   |   
> + | (iter 2)  |   | ramblock 2 pages |
> + | ...   |   | ...  |
> + -   
> + | ...   |   | ...  |
> + -   
> + | RAM_SAVE_FLAG_EOS|
> + 
> + | ...  |
> + 
> +
> + where:

Super-nit: you can drop the " " otherwise it's put into the quote.

> +  - ramblock header: the generic information for a ramblock, such as
> +idstr, used_len, etc.
> +
> +  - ramblock fixed-ram header: the information added by this feature:
> +bitmap of pages written, bitmap size and offset of pages in the
> +migration file.
> +
> +Restrictions
> +
> +
> +Since pages are written to their relative offsets and out of order
> +(due to the memory dirtying patterns), streaming channels such as
> +sockets are not supported. A seekable channel such as a file is
> +required. This can be verified in the QIOChannel by the presence of
> +the QIO_CHANNEL_FEATURE_SEEKABLE.

Would it worth also mention that it only provides fixed offsets to "guest
physical RAM" only?  For example, GPU RAM won't apply as they're migrated
as part of device states, even if also iterable.  IOW, IIUC if there's a
VFIO device (or a few), the fixed-ram migration file will still be unbound
in size, because device can keep flushing stale vRAM to the image..

Maybe that's too specific, I'll leave that to you to decide whether to even
mention it.

-- 
Peter Xu




Re: [PATCH v4 12/34] migration: Add fixed-ram URI compatibility check

2024-02-25 Thread Peter Xu
On Tue, Feb 20, 2024 at 07:41:16PM -0300, Fabiano Rosas wrote:
> The fixed-ram migration format needs a channel that supports seeking
> to be able to write each page to an arbitrary offset in the migration
> stream.
> 
> Signed-off-by: Fabiano Rosas 
> Reviewed-by: Daniel P. Berrangé 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH v4 11/34] migration/ram: Introduce 'fixed-ram' migration capability

2024-02-25 Thread Peter Xu
On Tue, Feb 20, 2024 at 07:41:15PM -0300, Fabiano Rosas wrote:
> Add a new migration capability 'fixed-ram'.
> 
> The core of the feature is to ensure that each RAM page has a specific
> offset in the resulting migration stream. The reasons why we'd want
> such behavior are:
> 
>  - The resulting file will have a bounded size, since pages which are
>dirtied multiple times will always go to a fixed location in the
>file, rather than constantly being added to a sequential
>stream. This eliminates cases where a VM with, say, 1G of RAM can
>result in a migration file that's 10s of GBs, provided that the
>workload constantly redirties memory.
> 
>  - It paves the way to implement O_DIRECT-enabled save/restore of the
>migration stream as the pages are ensured to be written at aligned
>offsets.
> 
>  - It allows the usage of multifd so we can write RAM pages to the
>migration file in parallel.
> 
> For now, enabling the capability has no effect. The next couple of
> patches implement the core functionality.
> 
> Signed-off-by: Fabiano Rosas 
> ---
> - update migration.json to 9.0 and improve wording
> - move docs to a separate file and add use cases information
> ---
>  docs/devel/migration/features.rst  |   1 +
>  docs/devel/migration/fixed-ram.rst | 137 +
>  migration/options.c|  34 +++
>  migration/options.h|   1 +
>  migration/savevm.c |   1 +
>  qapi/migration.json|   6 +-
>  6 files changed, 179 insertions(+), 1 deletion(-)
>  create mode 100644 docs/devel/migration/fixed-ram.rst
> 
> diff --git a/docs/devel/migration/features.rst 
> b/docs/devel/migration/features.rst
> index a9acaf618e..4c708b679a 100644
> --- a/docs/devel/migration/features.rst
> +++ b/docs/devel/migration/features.rst
> @@ -10,3 +10,4 @@ Migration has plenty of features to support different use 
> cases.
> dirty-limit
> vfio
> virtio
> +   fixed-ram
> diff --git a/docs/devel/migration/fixed-ram.rst 
> b/docs/devel/migration/fixed-ram.rst
> new file mode 100644
> index 00..a6c0e5a360
> --- /dev/null
> +++ b/docs/devel/migration/fixed-ram.rst
> @@ -0,0 +1,137 @@
> +Fixed-ram
> +=
> +
> +Fixed-ram is a new stream format for the RAM section designed to
> +supplement the existing ``file:`` migration and make it compatible
> +with ``multifd``. This enables parallel migration of a guest's RAM to
> +a file.
> +
> +The core of the feature is to ensure that each RAM page has a specific
> +offset in the resulting migration file. This enables the ``multifd``
> +threads to write exclusively to those offsets even if the guest is
> +constantly dirtying pages (i.e. live migration). Another benefit is
> +that the resulting file will have a bounded size, since pages which
> +are dirtied multiple times will always go to a fixed location in the
> +file, rather than constantly being added to a sequential
> +stream. Having the pages at fixed offsets also allows the usage of
> +O_DIRECT for save/restore of the migration stream as the pages are
> +ensured to be written respecting O_DIRECT alignment restrictions.
> +
> +Usage
> +-
> +
> +On both source and destination, enable the ``multifd`` and
> +``fixed-ram`` capabilities:
> +
> +``migrate_set_capability multifd on``
> +
> +``migrate_set_capability fixed-ram on``
> +
> +Use a ``file:`` URL for migration:
> +
> +``migrate file:/path/to/migration/file``
> +
> +Fixed-ram migration is best done non-live, i.e. by stopping the VM on
> +the source side before migrating.
> +
> +For best performance enable the ``direct-io`` capability as well:
> +
> +``migrate_set_capability direct-io on``
> +
> +Use-cases
> +-
> +
> +The fixed-ram feature was designed for use cases where the migration
> +stream will be directed to a file in the filesystem and not
> +immediately restored on the destination VM [#]_. These could be
> +thought of as snapshots. We can further categorize them into live and
> +non-live.
> +
> +- Non-live snapshot
> +
> +If the use case requires a VM to be stopped before taking a snapshot,
> +that's the ideal scenario for fixed-ram migration. Not having to track
> +dirty pages, the migration will write the RAM pages to the disk as
> +fast as it can.
> +
> +Note: if a snapshot is taken of a running VM, but the VM will be
> +stopped after the snapshot by the admin, then consider stopping it
> +right before the snapshot to take benefit of the performance gains
> +mentioned above.
> +
> +- Live snapshot
> +
> +If the use case requires that the VM keeps running during and after
> +the snapshot operation, then fixed-ram migration can still be used,
> +but will be less performant. Other strategies such as
> +background-snapshot should be evaluated as well. One benefit of
> +fixed-ram in this scenario is portability since background-snapshot
> +depends on async dirty tracking (KVM_GET_DIRTY_LOG) which is not

Background snapshot uses 

Re: [PATCH] spapr: avoid overhead of finding vhyp class in critical operations

2024-02-25 Thread David Gibson
On Sat, Feb 24, 2024 at 05:33:59PM +1000, Nicholas Piggin wrote:
> PPC_VIRTUAL_HYPERVISOR_GET_CLASS is used in critical operations like
> interrupts and TLB misses and is quite costly. Running the
> kvm-unit-tests sieve program with radix MMU enabled thrashes the TCG
> TLB and spends a lot of time in TLB and page table walking code. The
> test takes 67 seconds to complete with a lot of time being spent in
> code related to finding the vhyp class:
> 
>12.01%  [.] g_str_hash
> 8.94%  [.] g_hash_table_lookup
> 8.06%  [.] object_class_dynamic_cast
> 6.21%  [.] address_space_ldq
> 4.94%  [.] __strcmp_avx2
> 4.28%  [.] tlb_set_page_full
> 4.08%  [.] address_space_translate_internal
> 3.17%  [.] object_class_dynamic_cast_assert
> 2.84%  [.] ppc_radix64_xlate
> 
> Keep a pointer to the class and avoid this lookup. This reduces the
> execution time to 40 seconds.
> 
> Signed-off-by: Nicholas Piggin 
> ---
> This feels a bit ugly, but the performance problem of looking up the
> class in fast paths can't be ignored. Is there a "nicer" way to get the
> same result?

Not one I'm aware of, unfortunately.

> 
> Thanks,
> Nick
> 
>  target/ppc/cpu.h   |  3 ++-
>  target/ppc/mmu-book3s-v3.h |  4 +---
>  hw/ppc/pegasos2.c  |  1 +
>  target/ppc/cpu_init.c  |  9 +++--
>  target/ppc/excp_helper.c   | 16 
>  target/ppc/kvm.c   |  4 +---
>  target/ppc/mmu-hash64.c| 16 
>  target/ppc/mmu-radix64.c   |  4 +---
>  8 files changed, 17 insertions(+), 40 deletions(-)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index ec14574d14..eb85d9aa71 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -1437,6 +1437,7 @@ struct ArchCPU {
>  int vcpu_id;
>  uint32_t compat_pvr;
>  PPCVirtualHypervisor *vhyp;
> +PPCVirtualHypervisorClass *vhyp_class;
>  void *machine_data;
>  int32_t node_id; /* NUMA node this CPU belongs to */
>  PPCHash64Options *hash64_opts;
> @@ -1535,7 +1536,7 @@ DECLARE_OBJ_CHECKERS(PPCVirtualHypervisor, 
> PPCVirtualHypervisorClass,
>  
>  static inline bool vhyp_cpu_in_nested(PowerPCCPU *cpu)
>  {
> -return PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp)->cpu_in_nested(cpu);
> +return cpu->vhyp_class->cpu_in_nested(cpu);
>  }
>  #endif /* CONFIG_USER_ONLY */
>  
> diff --git a/target/ppc/mmu-book3s-v3.h b/target/ppc/mmu-book3s-v3.h
> index 674377a19e..f3f7993958 100644
> --- a/target/ppc/mmu-book3s-v3.h
> +++ b/target/ppc/mmu-book3s-v3.h
> @@ -108,9 +108,7 @@ static inline hwaddr ppc_hash64_hpt_mask(PowerPCCPU *cpu)
>  uint64_t base;
>  
>  if (cpu->vhyp) {
> -PPCVirtualHypervisorClass *vhc =
> -PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
> -return vhc->hpt_mask(cpu->vhyp);
> +return cpu->vhyp_class->hpt_mask(cpu->vhyp);
>  }
>  if (cpu->env.mmu_model == POWERPC_MMU_3_00) {
>  ppc_v3_pate_t pate;
> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
> index 04d6decb2b..c22e8b336d 100644
> --- a/hw/ppc/pegasos2.c
> +++ b/hw/ppc/pegasos2.c
> @@ -400,6 +400,7 @@ static void pegasos2_machine_reset(MachineState *machine, 
> ShutdownCause reason)
>  machine->fdt = fdt;
>  
>  pm->cpu->vhyp = PPC_VIRTUAL_HYPERVISOR(machine);
> +pm->cpu->vhyp_class = PPC_VIRTUAL_HYPERVISOR_GET_CLASS(pm->cpu->vhyp);
>  }
>  
>  enum pegasos2_rtas_tokens {
> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> index 9bccddb350..63d0094024 100644
> --- a/target/ppc/cpu_init.c
> +++ b/target/ppc/cpu_init.c
> @@ -6631,6 +6631,7 @@ void cpu_ppc_set_vhyp(PowerPCCPU *cpu, 
> PPCVirtualHypervisor *vhyp)
>  CPUPPCState *env = >env;
>  
>  cpu->vhyp = vhyp;
> +cpu->vhyp_class = PPC_VIRTUAL_HYPERVISOR_GET_CLASS(vhyp);
>  
>  /*
>   * With a virtual hypervisor mode we never allow the CPU to go
> @@ -7224,9 +7225,7 @@ static void ppc_cpu_exec_enter(CPUState *cs)
>  PowerPCCPU *cpu = POWERPC_CPU(cs);
>  
>  if (cpu->vhyp) {
> -PPCVirtualHypervisorClass *vhc =
> -PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
> -vhc->cpu_exec_enter(cpu->vhyp, cpu);
> +cpu->vhyp_class->cpu_exec_enter(cpu->vhyp, cpu);
>  }
>  }
>  
> @@ -7235,9 +7234,7 @@ static void ppc_cpu_exec_exit(CPUState *cs)
>  PowerPCCPU *cpu = POWERPC_CPU(cs);
>  
>  if (cpu->vhyp) {
> -PPCVirtualHypervisorClass *vhc =
> -PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
> -vhc->cpu_exec_exit(cpu->vhyp, cpu);
> +cpu->vhyp_class->cpu_exec_exit(cpu->vhyp, cpu);
>  }
>  }
>  #endif /* CONFIG_TCG */
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 98952de267..445350488c 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -840,9 +840,7 @@ static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
>   * HV mode, we need to keep hypercall support.
>   */
>  if (lev == 1 && cpu->vhyp) {
> -

Re: [PATCH V1] migration: export fewer options

2024-02-25 Thread Peter Xu
On Fri, Feb 23, 2024 at 09:13:24AM -0800, Steve Sistare wrote:
> A small number of migration options are accessed by migration clients,
> but to see them clients must include all of options.h, which is mostly
> for migration core code.  migrate_mode() in particular will be needed by
> multiple clients.
> 
> Refactor the option declarations so clients can see the necessary few via
> misc.h, which already exports a portion of the client API.
> 
> Signed-off-by: Steve Sistare 

Sounds reasonable, queued, thanks.

> ---
> I suggest that eventually we should define a single file migration/client.h
> which exports everything needed by the simpler clients: blockers, notifiers,
> options, cpr, and state accessors.

What's the difference v.s. current migration/misc.h?

-- 
Peter Xu




Re: [RFC PATCH v3 04/21] target/arm: Implement ALLINT MSR (immediate)

2024-02-25 Thread Jinjie Ruan via



On 2024/2/24 3:03, Richard Henderson wrote:
> On 2/23/24 00:32, Jinjie Ruan via wrote:
>> Add ALLINT MSR (immediate) to decodetree. And the EL0 check is necessary
>> to ALLINT. Avoid the unconditional write to pc and use raise_exception_ra
>> to unwind.
>>
>> Signed-off-by: Jinjie Ruan 
>> ---
>> v3:
>> - Remove EL0 check in allint_check().
>> - Add TALLINT check for EL1 in allint_check().
>> - Remove unnecessarily arm_rebuild_hflags() in msr_i_allint helper.
>> ---
>>   target/arm/tcg/a64.decode  |  1 +
>>   target/arm/tcg/helper-a64.c    | 24 
>>   target/arm/tcg/helper-a64.h    |  1 +
>>   target/arm/tcg/translate-a64.c | 10 ++
>>   4 files changed, 36 insertions(+)
>>
>> diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
>> index 8a20dce3c8..3588080024 100644
>> --- a/target/arm/tcg/a64.decode
>> +++ b/target/arm/tcg/a64.decode
>> @@ -207,6 +207,7 @@ MSR_i_DIT   1101 0101  0 011 0100  010
>> 1 @msr_i
>>   MSR_i_TCO   1101 0101  0 011 0100  100 1 @msr_i
>>   MSR_i_DAIFSET   1101 0101  0 011 0100  110 1 @msr_i
>>   MSR_i_DAIFCLEAR 1101 0101  0 011 0100  111 1 @msr_i
>> +MSR_i_ALLINT    1101 0101  0 001 0100  000 1 @msr_i
> 
> Decode is incorrect either here, or in trans_MSR_i_ALLINT, because CRm
> != '000x' is UNDEFINED.
> 
> MSR_i_ALLINT    1101 0101  0 001 0100 000 imm:1 000 1
> 
> is perhaps the clearest implementation.
> 
>> +static void allint_check(CPUARMState *env, uint32_t op,
>> +   uint32_t imm, uintptr_t ra)
>> +{
>> +    /* ALLINT update to PSTATE. */
>> +    if (arm_current_el(env) == 1 && arm_is_el2_enabled(env) &&
>> +    (arm_hcrx_el2_eff(env) & HCRX_TALLINT)) {
>> +    raise_exception_ra(env, EXCP_UDEF,
>> +   syn_aa64_sysregtrap(0, extract32(op, 0, 3),
>> +   extract32(op, 3, 3), 4,
>> +   imm, 0x1f, 0),
>> +   exception_target_el(env), ra);
>> +    }
>> +}
>> +
>> +void HELPER(msr_i_allint)(CPUARMState *env, uint32_t imm)
>> +{
>> +    allint_check(env, 0x8, imm, GETPC());
> 
> As previously noted, the check for MSR_i only applies to imm==1, not 0.

Sorry! The hardware manual I looked at didn't say this.

> 
> As previously noted, with ALLINT in env->pstate, you can implement this
> completely inline for EL[23], or EL1 with imm==0.
> 
> No point in passing in "op" and extracting, because you know exactly
> what the value should be for all MSR ALLINT.
> 
> 
> r~



Re: [PATCH V4 00/14] allow cpr-reboot for vfio

2024-02-25 Thread Peter Xu
On Thu, Feb 22, 2024 at 12:33:42PM -0500, Steven Sistare wrote:
> Peter (and David if interested): these patches still need RB:
>   migration: notifier error checking
>   migration: stop vm for cpr
>   migration: update cpr-reboot description
>   migration: options incompatible with cpr

These all look fine to me.

> 
> Alex, these patches still need RB:
>   vfio: register container for cpr
>   vfio: allow cpr-reboot migration if suspended

I'll need to wait for comment from either Alex/Cedric on these.

As I asked in the other thread, afaict crp-reboot keeps changing behavior,
maybe I can merge migration patches first, then keep vfio patches
separately merged / discussed?  I always see cpr-reboot mode experimental
from this regard.  Please consider adding a patch to declare cpr-reboot
mode experimental if that matches your expectation, until all relevant
patches are merged, to make sure the ABI becomes stable.

Thanks,

-- 
Peter Xu




Re: [PATCH V4 14/14] migration: options incompatible with cpr

2024-02-25 Thread Peter Xu
On Thu, Feb 22, 2024 at 09:28:40AM -0800, Steve Sistare wrote:
> Fail the migration request if options are set that are incompatible
> with cpr.
> 
> Signed-off-by: Steve Sistare 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH V4 13/14] migration: update cpr-reboot description

2024-02-25 Thread Peter Xu
On Thu, Feb 22, 2024 at 09:28:39AM -0800, Steve Sistare wrote:
> Clarify qapi for cpr-reboot migration mode, and add vfio support.
> 
> Signed-off-by: Steve Sistare 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH V4 10/14] migration: stop vm for cpr

2024-02-25 Thread Peter Xu
On Thu, Feb 22, 2024 at 09:28:36AM -0800, Steve Sistare wrote:
> When migration for cpr is initiated, stop the vm and set state
> RUN_STATE_FINISH_MIGRATE before ram is saved.  This eliminates the
> possibility of ram and device state being out of sync, and guarantees
> that a guest in the suspended state remains suspended, because qmp_cont
> rejects a cont command in the RUN_STATE_FINISH_MIGRATE state.
> 
> Signed-off-by: Steve Sistare 

Reviewed-by: Peter Xu 

cpr-reboot mode keeps changing behavior.

Could we declare it "experimental" until it's solid?  Maybe a patch to
document this?

Normally IMHO we shouldn't merge a feature if it's not complete, however
cpr-reboot is so special that the mode itself is already merged in 8.2
before I started to merge patches, and it keeps changing things.  I don't
know what else we can do here besides declaring it experimental and not
declare it a stable feature.

-- 
Peter Xu




Re: [PATCH V4 09/14] migration: notifier error checking

2024-02-25 Thread Peter Xu
On Thu, Feb 22, 2024 at 09:28:35AM -0800, Steve Sistare wrote:
> Check the status returned by migration notifiers for event type
> MIG_EVENT_PRECOPY_SETUP, and report errors.  None of the notifiers
> return an error status at this time.
> 
> Signed-off-by: Steve Sistare 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH] migration: Fix qmp_query_migrate mbps value

2024-02-25 Thread Peter Xu
On Fri, Feb 23, 2024 at 09:39:12AM -0300, Fabiano Rosas wrote:
> I've been planning to merge migration_completion() and
> migration_iteration_finish(). It's too unintuitive to do the completion
> routine deep inside migration_iteration_run(). AFAICS those are all tail
> calls, so we could bring migration_completion() up into the
> migration_thread top level.
> 
> So if you'll allow me I think I'll refrain from moving the state into
> migration_calculate_complete() for now.

Yep go ahead, I'll read the patches.

-- 
Peter Xu




Re: [External] Re: [PATCH v2 4/7] migration/multifd: Enable zero page checking from multifd threads.

2024-02-25 Thread Peter Xu
On Sat, Feb 24, 2024 at 03:03:15PM -0800, Hao Xiang wrote:
> So I just want to make sure I am coding the right solution. I added
> setting "zero-page-detection" to "legacy" in hw_compat_8_2 and tested
> it. The behavior is that if I set machine type to pc-q35-8.2,
> zero-page-detection will automatically be set to "legacy". But if I
> set the machine type to pc-q35-9.0, zero-page-detection will be the
> default value "multifd". However, this doesn't seem to be a hard
> requirement because I can still override zero-page-detection to
> multifd on machine type pc-q35-8.2. Is this OK?

What we want to guarantee is old 8.2 users can smoothly migrate to the new
qemus, and existing 8.2 (or prior) users definitely don't have any override
over the new parameter zero-page-detection simply because 8.2 (or prior)
binary doesn't support it yet.

Then, if someone is using new binary with 8.2 machine types, meanwhile
override this default value, it means it's the user's choice of doing this,
and the user should guarantee all the qemus he/she manages also keeps this
parameter override to make sure migration will work between these qemu
processes.

So in short, that's all fine.

Thanks,

-- 
Peter Xu




Re: [PATCH 0/2] RISC-V: Add Ztso extension

2024-02-25 Thread Alistair Francis
On Wed, Feb 7, 2024 at 10:24 PM Christoph Müllner
 wrote:
>
> The first patch of this series picks up an earlier v2 Ztso patch from Palmer,
> which can be found here:
>   
> https://patchwork.kernel.org/project/qemu-devel/patch/20220917072635.11616-1-pal...@rivosinc.com/
> This patch did not apply cleanly but the necessary changes were trivial.
> There was a request to extend the commit message, which is part of the
> posted patch of this series.  As this patch was reviewed a year ago,
> I believe it could be merged.
>
> The second patch simply exposes Ztso via hwprobe.
>
> Relevant in this context might be also, that Richard's patch to improve
> TCG's memory barrier selection depending on host and guest memory ordering
> landed in June 2023:
>   
> https://lore.kernel.org/all/a313b36b-dcc1-f812-ccbd-afed1cbd5...@linaro.org/T/
>
> The first patch was already sent as part of an RFC series for Ssdtso:
>   https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg02962.html
> Since I don't want to keep this patch until the ratification of Ssdtso,
> I would like to get this merged independent of Ssdtso.
>
> This series is based on today's riscv-to-apply.next with my other series
> that adds the new hwprobe keys
> (https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg01293.html).
>
> This series can also be found here:
>   https://github.com/cmuellner/qemu/tree/ztso
>
> Christoph Müllner (1):
>   linux-user/riscv: Add Ztso extension to hwprobe
>
> Palmer Dabbelt (1):
>   RISC-V: Add support for Ztso

Thanks!

Applied to riscv-to-apply.next

Alistair

>
>  linux-user/syscall.c|  3 +++
>  target/riscv/cpu.c  |  2 ++
>  target/riscv/cpu_cfg.h  |  1 +
>  target/riscv/insn_trans/trans_rva.c.inc | 11 ---
>  target/riscv/insn_trans/trans_rvi.c.inc | 16 ++--
>  target/riscv/insn_trans/trans_rvv.c.inc | 20 
>  target/riscv/translate.c|  3 +++
>  7 files changed, 51 insertions(+), 5 deletions(-)
>
> --
> 2.43.0
>
>



Re: [PATCH 2/2] linux-user/riscv: Add Ztso extension to hwprobe

2024-02-25 Thread Alistair Francis
On Wed, Feb 7, 2024 at 10:25 PM Christoph Müllner
 wrote:
>
> This patch exposes Ztso via hwprobe in QEMU's user space emulator.
>
> Signed-off-by: Christoph Müllner 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  linux-user/syscall.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 3ba20f99ad..24fa11d946 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8826,6 +8826,7 @@ static int do_getdents64(abi_long dirfd, abi_long arg2, 
> abi_long count)
>  #defineRISCV_HWPROBE_EXT_ZVFH  (1 << 30)
>  #defineRISCV_HWPROBE_EXT_ZVFHMIN   (1 << 31)
>  #defineRISCV_HWPROBE_EXT_ZFA   (1ULL << 32)
> +#defineRISCV_HWPROBE_EXT_ZTSO  (1ULL << 33)
>  #defineRISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
>  #defineRISCV_HWPROBE_EXT_ZICOND(1ULL << 35)
>
> @@ -8940,6 +8941,8 @@ static void risc_hwprobe_fill_pairs(CPURISCVState *env,
>   RISCV_HWPROBE_EXT_ZVFHMIN : 0;
>  value |= cfg->ext_zfa ?
>   RISCV_HWPROBE_EXT_ZFA : 0;
> +value |= cfg->ext_ztso ?
> + RISCV_HWPROBE_EXT_ZTSO : 0;
>  value |= cfg->ext_zacas ?
>   RISCV_HWPROBE_EXT_ZACAS : 0;
>  value |= cfg->ext_zicond ?
> --
> 2.43.0
>
>



Re: [External] Re: [PATCH v2 3/7] migration/multifd: Zero page transmission on the multifd thread.

2024-02-25 Thread Peter Xu
On Sat, Feb 24, 2024 at 02:56:15PM -0800, Hao Xiang wrote:
> > > > I don't think it's super clean to have three arrays offset, zero and
> > > > normal, all sized for the full packet size. It might be possible to just
> > > > carry a bitmap of non-zero pages along with pages->offset and operate on
> > > > that instead.
> > > >
> > > > What do you think?
> > > >
> > > > Peter, any ideas? Should we just leave this for another time?
> > >
> > > Yeah I think a bitmap should save quite a few fields indeed, it'll however
> > > make the latter iteration slightly harder by walking both (offset[],
> > > bitmap), process the page only if bitmap is set for the offset.
> > >
> > > IIUC we perhaps don't even need a bitmap?  AFAIU what we only need in
> > > Multifdpages_t is one extra field to mark "how many normal pages", aka,
> > > normal_num here (zero_num can be calculated from num-normal_num).  Then
> > > the zero page detection logic should do two things:
> > >
> > >   - Sort offset[] array so that it starts with normal pages, followed up 
> > > by
> > > zero pages
> > >
> > >   - Setup normal_num to be the number of normal pages
> > >
> > > Then we reduce 2 new arrays (normal[], zero[]) + 2 new fields (normal_num,
> > > zero_num) -> 1 new field (normal_num).  It'll also be trivial to fill the
> > > packet header later because offset[] is exactly that.
> > >
> > > Side note - I still think it's confusing to read this patch and previous
> > > patch separately.  Obviously previous patch introduced these new fields
> > > without justifying their values yet.  IMHO it'll be easier to review if 
> > > you
> > > merge the two patches.
> >
> > Fabiano, thanks for catching this. I totally missed the backward
> > compatibility thing.
> > Peter, I will code the sorting and merge this patch with the previous one.
> >
> It turns out that we still need to add a "zero_pages" field in
> MultiFDPacket_t because the existing field "pages_alloc" is not the
> total number of pages in "offset". So source can set "zero_pages" from
> pages->num - pages->num_normal but "zero_pages" needs to be set in the
> packet.

Yes, one more field should be needed in MultiFDPacket_t.  Noet that what I
said above was about Multifdpages_t, not MultiFDPacket_t (which is the wire
protocol instead).  To support zero page offloading we should need one more
field for each.

IMHO MultiFDPacket_t.pages_alloc is redundant and actually not useful..
It's just that it existed in the wire protocol already so maybe we'd still
better keep it there..

-- 
Peter Xu




Re: [PATCH 1/2] RISC-V: Add support for Ztso

2024-02-25 Thread Alistair Francis
On Wed, Feb 7, 2024 at 10:25 PM Christoph Müllner
 wrote:
>
> From: Palmer Dabbelt 
>
> The Ztso extension is already ratified, this adds it as a CPU property
> and adds various fences throughout the port in order to allow TSO
> targets to function on weaker hosts.  We need no fences for AMOs as
> they're already SC, the places we need barriers are described.
> These fences are placed in the RISC-V backend rather than TCG as is
> planned for x86-on-arm64 because RISC-V allows heterogeneous (and
> likely soon dynamic) hart memory models.
>
> Reviewed-by: Daniel Henrique Barboza 
> Signed-off-by: Palmer Dabbelt 
> Signed-off-by: Christoph Müllner 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c  |  2 ++
>  target/riscv/cpu_cfg.h  |  1 +
>  target/riscv/insn_trans/trans_rva.c.inc | 11 ---
>  target/riscv/insn_trans/trans_rvi.c.inc | 16 ++--
>  target/riscv/insn_trans/trans_rvv.c.inc | 20 
>  target/riscv/translate.c|  3 +++
>  6 files changed, 48 insertions(+), 5 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 1b8d001d23..b679ecd8c7 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -143,6 +143,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
>  ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
>  ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
>  ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
> +ISA_EXT_DATA_ENTRY(ztso, PRIV_VERSION_1_12_0, ext_ztso),
>  ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
>  ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
>  ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
> @@ -1488,6 +1489,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
>  MULTI_EXT_CFG_BOOL("zksed", ext_zksed, false),
>  MULTI_EXT_CFG_BOOL("zksh", ext_zksh, false),
>  MULTI_EXT_CFG_BOOL("zkt", ext_zkt, false),
> +MULTI_EXT_CFG_BOOL("ztso", ext_ztso, false),
>
>  MULTI_EXT_CFG_BOOL("zdinx", ext_zdinx, false),
>  MULTI_EXT_CFG_BOOL("zfinx", ext_zfinx, false),
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index 833bf58217..afba8ed0b2 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -71,6 +71,7 @@ struct RISCVCPUConfig {
>  bool ext_zihintntl;
>  bool ext_zihintpause;
>  bool ext_zihpm;
> +bool ext_ztso;
>  bool ext_smstateen;
>  bool ext_sstc;
>  bool ext_svadu;
> diff --git a/target/riscv/insn_trans/trans_rva.c.inc 
> b/target/riscv/insn_trans/trans_rva.c.inc
> index 267930e5bc..4a9e4591d1 100644
> --- a/target/riscv/insn_trans/trans_rva.c.inc
> +++ b/target/riscv/insn_trans/trans_rva.c.inc
> @@ -40,7 +40,11 @@ static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp 
> mop)
>  tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
>  }
>  tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
> -if (a->aq) {
> +/*
> + * TSO defines AMOs as acquire+release-RCsc, but does not define LR/SC as
> + * AMOs.  Instead treat them like loads.
> + */
> +if (a->aq || ctx->ztso) {
>  tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
>  }
>
> @@ -76,9 +80,10 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp 
> mop)
>  gen_set_label(l1);
>  /*
>   * Address comparison failure.  However, we still need to
> - * provide the memory barrier implied by AQ/RL.
> + * provide the memory barrier implied by AQ/RL/TSO.
>   */
> -tcg_gen_mb(TCG_MO_ALL + a->aq * TCG_BAR_LDAQ + a->rl * TCG_BAR_STRL);
> +TCGBar bar_strl = (ctx->ztso || a->rl) ? TCG_BAR_STRL : 0;
> +tcg_gen_mb(TCG_MO_ALL + a->aq * TCG_BAR_LDAQ + bar_strl);
>  gen_set_gpr(ctx, a->rd, tcg_constant_tl(1));
>
>  gen_set_label(l2);
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
> b/target/riscv/insn_trans/trans_rvi.c.inc
> index faf6d65064..ad40d3e87f 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -266,12 +266,20 @@ static bool gen_load_i128(DisasContext *ctx, arg_lb *a, 
> MemOp memop)
>
>  static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
>  {
> +bool out;
> +
>  decode_save_opc(ctx);
>  if (get_xl(ctx) == MXL_RV128) {
> -return gen_load_i128(ctx, a, memop);
> +out = gen_load_i128(ctx, a, memop);
>  } else {
> -return gen_load_tl(ctx, a, memop);
> +out = gen_load_tl(ctx, a, memop);
> +}
> +
> +if (ctx->ztso) {
> +tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
>  }
> +
> +return out;
>  }
>
>  static bool trans_lb(DisasContext *ctx, arg_lb *a)
> @@ -328,6 +336,10 @@ static bool gen_store_tl(DisasContext *ctx, arg_sb *a, 
> MemOp memop)
>  TCGv addr = get_address(ctx, a->rs1, a->imm);
>  TCGv data = get_gpr(ctx, a->rs2, EXT_NONE);
>
> +if (ctx->ztso) {
> +tcg_gen_mb(TCG_MO_ALL | 

RE: [PATCH v2 0/4] RISC-V: Modularize common match conditions for trigger

2024-02-25 Thread 張哲嘉
Hi Alistair,

> -Original Message-
> From: Alistair Francis 
> Sent: Monday, February 26, 2024 8:25 AM
> To: Alvin Che-Chia Chang(張哲嘉) 
> Cc: qemu-ri...@nongnu.org; qemu-devel@nongnu.org;
> alistair.fran...@wdc.com; bin.m...@windriver.com; liwei1...@gmail.com;
> dbarb...@ventanamicro.com; zhiwei_...@linux.alibaba.com
> Subject: Re: [PATCH v2 0/4] RISC-V: Modularize common match conditions for
> trigger
>
> [EXTERNAL MAIL 外部信件]
>
> On Fri, Feb 23, 2024 at 12:22 PM Alvin Chang via 
> wrote:
> >
> > According to RISC-V Debug specification, the enabled privilege levels
> > of
>
> Can you specify what version of the debug spec?

In general, this series does not add any new functionalities.
The original implementation has duplicated code in type 2/3/6 triggers.
I just eliminated those code and modularized them to be trigger_common_match().
Besides, we may want to check other conditions in the future, so this function 
can be used for those purposes.

When I track the commit history, it seems the code is submitted in the 
following commits two years ago:
https://github.com/qemu/qemu/commit/95799e36c15a9ab602a388491c40f6860f6ae8bf
https://github.com/qemu/qemu/commit/b5f6379d134bd201d52380c73ff73565e6a4321e
https://github.com/qemu/qemu/commit/c32461d8eeb17490b1b1e969e2ce8f1ecd83bfbb
https://github.com/qemu/qemu/commit/c472c142a7552f5b0e40378d5643a2810ef1b111

Since they mentioned the "type 6" trigger and "Sdtrig" extension, I assume 
current implementation is based on Debug Spec version 1.0
There is no type 6 trigger and Sdtrig extension in Debug Spec version 0.13

Sincerely,
Alvin Chang

>
> Ideally if you can link directly to the PDF that would be very useful.
> There are multiple versions so it's hard to keep track of.
>
> Alistair
>
> > the trigger is common match conditions for all the types of the trigger.
> > This series modularize the code for checking the privilege levels of
> > type 2/3/6 triggers by implementing functions trigger_common_match()
> > and trigger_priv_match().
> >
> > Additional match conditions, such as CSR tcontrol and textra, can be
> > further implemented into trigger_common_match() in the future.
> >
> > Changes from v1:
> > - Fix typo
> > - Add commit description for changing behavior of looping the triggers
> >   when we check type 2 triggers.
> >
> > Alvin Chang (4):
> >   target/riscv: Add functions for common matching conditions of trigger
> >   target/riscv: Apply modularized matching conditions for breakpoint
> >   target/riscv: Apply modularized matching conditions for watchpoint
> >   target/riscv: Apply modularized matching conditions for icount
> > trigger
> >
> >  target/riscv/debug.c | 124
> > +--
> >  1 file changed, 83 insertions(+), 41 deletions(-)
> >
> > --
> > 2.34.1
> >
> >
CONFIDENTIALITY NOTICE:

This e-mail (and its attachments) may contain confidential and legally 
privileged information or information protected from disclosure. If you are not 
the intended recipient, you are hereby notified that any disclosure, copying, 
distribution, or use of the information contained herein is strictly 
prohibited. In this case, please immediately notify the sender by return 
e-mail, delete the message (and any accompanying documents) and destroy all 
printed hard copies. Thank you for your cooperation.

Copyright ANDES TECHNOLOGY CORPORATION - All Rights Reserved.


Re: [PATCH v2 0/4] RISC-V: Modularize common match conditions for trigger

2024-02-25 Thread Alistair Francis
On Fri, Feb 23, 2024 at 12:22 PM Alvin Chang via  wrote:
>
> According to RISC-V Debug specification, the enabled privilege levels of

Can you specify what version of the debug spec?

Ideally if you can link directly to the PDF that would be very useful.
There are multiple versions so it's hard to keep track of.

Alistair

> the trigger is common match conditions for all the types of the trigger.
> This series modularize the code for checking the privilege levels of
> type 2/3/6 triggers by implementing functions trigger_common_match()
> and trigger_priv_match().
>
> Additional match conditions, such as CSR tcontrol and textra, can be
> further implemented into trigger_common_match() in the future.
>
> Changes from v1:
> - Fix typo
> - Add commit description for changing behavior of looping the triggers
>   when we check type 2 triggers.
>
> Alvin Chang (4):
>   target/riscv: Add functions for common matching conditions of trigger
>   target/riscv: Apply modularized matching conditions for breakpoint
>   target/riscv: Apply modularized matching conditions for watchpoint
>   target/riscv: Apply modularized matching conditions for icount trigger
>
>  target/riscv/debug.c | 124 +--
>  1 file changed, 83 insertions(+), 41 deletions(-)
>
> --
> 2.34.1
>
>



Re: [PATCH v2 1/2] hw/arm: Use TYPE_OR_IRQ when connecting STM32L4x5 EXTI fan-in IRQs

2024-02-25 Thread Alistair Francis
On Wed, Feb 21, 2024 at 4:42 AM Inès Varhol
 wrote:
>
> Fixes: 52671f69f7a4 ("[PATCH v8 0/3] Add device STM32L4x5 EXTI")
> Signed-off-by: Inès Varhol 

Acked-by: Alistair Francis 

Alistair

> ---
>  include/hw/arm/stm32l4x5_soc.h |  4 ++
>  hw/arm/stm32l4x5_soc.c | 80 +-
>  2 files changed, 74 insertions(+), 10 deletions(-)
>
> diff --git a/include/hw/arm/stm32l4x5_soc.h b/include/hw/arm/stm32l4x5_soc.h
> index baf70410b5..4f314b7a93 100644
> --- a/include/hw/arm/stm32l4x5_soc.h
> +++ b/include/hw/arm/stm32l4x5_soc.h
> @@ -26,6 +26,7 @@
>
>  #include "exec/memory.h"
>  #include "hw/arm/armv7m.h"
> +#include "hw/or-irq.h"
>  #include "hw/misc/stm32l4x5_syscfg.h"
>  #include "hw/misc/stm32l4x5_exti.h"
>  #include "qom/object.h"
> @@ -36,12 +37,15 @@
>  #define TYPE_STM32L4X5XG_SOC "stm32l4x5xg-soc"
>  OBJECT_DECLARE_TYPE(Stm32l4x5SocState, Stm32l4x5SocClass, STM32L4X5_SOC)
>
> +#define NUM_EXTI_OR_GATES 4
> +
>  struct Stm32l4x5SocState {
>  SysBusDevice parent_obj;
>
>  ARMv7MState armv7m;
>
>  Stm32l4x5ExtiState exti;
> +OrIRQState exti_or_gates[NUM_EXTI_OR_GATES];
>  Stm32l4x5SyscfgState syscfg;
>
>  MemoryRegion sram1;
> diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
> index f470ff74ec..d1786e0da1 100644
> --- a/hw/arm/stm32l4x5_soc.c
> +++ b/hw/arm/stm32l4x5_soc.c
> @@ -26,6 +26,7 @@
>  #include "qapi/error.h"
>  #include "exec/address-spaces.h"
>  #include "sysemu/sysemu.h"
> +#include "hw/or-irq.h"
>  #include "hw/arm/stm32l4x5_soc.h"
>  #include "hw/qdev-clock.h"
>  #include "hw/misc/unimp.h"
> @@ -42,21 +43,24 @@
>  #define NUM_EXTI_IRQ 40
>  /* Match exti line connections with their CPU IRQ number */
>  /* See Vector Table (Reference Manual p.396) */
> +/*
> + * Some IRQs are connected to the same CPU IRQ (denoted by -1)
> + * and require an intermediary OR gate to function correctly.
> + */
>  static const int exti_irq[NUM_EXTI_IRQ] = {
>  6,  /* GPIO[0] */
>  7,  /* GPIO[1] */
>  8,  /* GPIO[2] */
>  9,  /* GPIO[3] */
>  10, /* GPIO[4] */
> -23, 23, 23, 23, 23, /* GPIO[5..9]  */
> -40, 40, 40, 40, 40, 40, /* GPIO[10..15]*/
> -1,  /* PVD */
> +-1, -1, -1, -1, -1, /* GPIO[5..9] OR gate 23   */
> +-1, -1, -1, -1, -1, -1, /* GPIO[10..15] OR gate 40 */
> +-1, /* PVD OR gate 1   */
>  67, /* OTG_FS_WKUP, Direct */
>  41, /* RTC_ALARM   */
>  2,  /* RTC_TAMP_STAMP2/CSS_LSE */
>  3,  /* RTC wakeup timer*/
> -63, /* COMP1   */
> -63, /* COMP2   */
> +-1, -1, /* COMP[1..2] OR gate 63   */
>  31, /* I2C1 wakeup, Direct */
>  33, /* I2C2 wakeup, Direct */
>  72, /* I2C3 wakeup, Direct */
> @@ -69,18 +73,39 @@ static const int exti_irq[NUM_EXTI_IRQ] = {
>  65, /* LPTIM1, Direct  */
>  66, /* LPTIM2, Direct  */
>  76, /* SWPMI1 wakeup, Direct   */
> -1,  /* PVM1 wakeup */
> -1,  /* PVM2 wakeup */
> -1,  /* PVM3 wakeup */
> -1,  /* PVM4 wakeup */
> +-1, -1, -1, -1, /* PVM[1..4] OR gate 1 */
>  78  /* LCD wakeup, Direct  */
>  };
>
> +static const int exti_or_gates_out[NUM_EXTI_OR_GATES] = {
> +23, 40, 63, 1,
> +};
> +
> +static const int exti_or_gates_num_lines_in[NUM_EXTI_OR_GATES] = {
> +5, 6, 2, 5,
> +};
> +
> +/* 3 OR gates with consecutive inputs */
> +#define NUM_EXTI_SIMPLE_OR_GATES 3
> +static const int exti_or_gates_first_line_in[NUM_EXTI_SIMPLE_OR_GATES] = {
> +5, 10, 21,
> +};
> +
> +/* 1 OR gate with non-consecutive inputs */
> +#define EXTI_OR_GATE1_NUM_LINES_IN 5
> +static const int exti_or_gate1_lines_in[EXTI_OR_GATE1_NUM_LINES_IN] = {
> +16, 35, 36, 37, 38,
> +};
> +
>  static void stm32l4x5_soc_initfn(Object *obj)
>  {
>  Stm32l4x5SocState *s = STM32L4X5_SOC(obj);
>
>  object_initialize_child(obj, "exti", >exti, TYPE_STM32L4X5_EXTI);
> +for (unsigned i = 0; i < NUM_EXTI_OR_GATES; i++) {
> +object_initialize_child(obj, "exti_or_gates[*]", 
> >exti_or_gates[i],
> +TYPE_OR_IRQ);
> +}
>  object_initialize_child(obj, "syscfg", >syscfg, 
> TYPE_STM32L4X5_SYSCFG);
>
>  s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
> @@ -175,8 +200,43 @@ 

[PATCH v6 18/41] Add clock_isp stub

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 hw/arm/bcm2838_peripherals.c | 6 ++
 include/hw/arm/bcm2838_peripherals.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/hw/arm/bcm2838_peripherals.c b/hw/arm/bcm2838_peripherals.c
index 6badda3045..1f41028649 100644
--- a/hw/arm/bcm2838_peripherals.c
+++ b/hw/arm/bcm2838_peripherals.c
@@ -17,6 +17,9 @@
 #define PCIE_MMIO_ARM_OFFSET0x6
 #define PCIE_MMIO_SIZE  0x4000
 
+#define CLOCK_ISP_OFFSET0xc11000
+#define CLOCK_ISP_SIZE  0x100
+
 /* Lower peripheral base address on the VC (GPU) system bus */
 #define BCM2838_VC_PERI_LOW_BASE 0x7c00
 
@@ -228,6 +231,9 @@ static void bcm2838_peripherals_realize(DeviceState *dev, 
Error **errp)
 memory_region_add_subregion(get_system_memory(), PCIE_MMIO_ARM_OFFSET,
 mmio_mr);
 
+create_unimp(s_base, >clkisp, "bcm2835-clkisp", CLOCK_ISP_OFFSET,
+ CLOCK_ISP_SIZE);
+
 /* GPIO */
 if (!sysbus_realize(SYS_BUS_DEVICE(>gpio), errp)) {
 return;
diff --git a/include/hw/arm/bcm2838_peripherals.h 
b/include/hw/arm/bcm2838_peripherals.h
index 49bb4fab08..adc02894c1 100644
--- a/include/hw/arm/bcm2838_peripherals.h
+++ b/include/hw/arm/bcm2838_peripherals.h
@@ -77,6 +77,7 @@ struct BCM2838PeripheralState {
 OrIRQState dma_9_10_irq_orgate;
 
 UnimplementedDeviceState asb;
+UnimplementedDeviceState clkisp;
 };
 
 struct BCM2838PeripheralClass {
-- 
2.34.1




[PATCH v6 39/41] Add missed BCM2835 properties

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 hw/misc/bcm2835_property.c   | 21 +
 include/hw/arm/raspberrypi-fw-defs.h | 11 +++
 2 files changed, 32 insertions(+)

diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
index 5c48f8d743..bdd9a6bbce 100644
--- a/hw/misc/bcm2835_property.c
+++ b/hw/misc/bcm2835_property.c
@@ -19,6 +19,8 @@
 #include "trace.h"
 #include "hw/arm/raspi_platform.h"
 
+#define VCHI_BUSADDR_SIZE   sizeof(uint32_t)
+
 /* https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface */
 
 static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
@@ -138,6 +140,13 @@ static void 
bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
 resplen = 8;
 break;
 
+case RPI_FWREQ_GET_CLOCKS:
+/* TODO: add more clock IDs if needed */
+stl_le_phys(>dma_as, value + 12, 0);
+stl_le_phys(>dma_as, value + 16, RPI_FIRMWARE_ARM_CLK_ID);
+resplen = 8;
+break;
+
 case RPI_FWREQ_SET_CLOCK_RATE:
 case RPI_FWREQ_SET_MAX_CLOCK_RATE:
 case RPI_FWREQ_SET_MIN_CLOCK_RATE:
@@ -276,6 +285,7 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState 
*s, uint32_t value)
 stl_le_phys(>dma_as, value + 12, 0);
 resplen = 4;
 break;
+
 case RPI_FWREQ_FRAMEBUFFER_GET_NUM_DISPLAYS:
 stl_le_phys(>dma_as, value + 12, 1);
 resplen = 4;
@@ -301,6 +311,17 @@ static void 
bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
 resplen);
 break;
 
+case RPI_FWREQ_GET_THROTTLED:
+stl_le_phys(>dma_as, value + 12, 0);
+resplen = 4;
+break;
+
+case RPI_FWREQ_VCHIQ_INIT:
+stl_le_phys(>dma_as,
+value + offsetof(rpi_firmware_prop_request_t, payload),
+0);
+resplen = VCHI_BUSADDR_SIZE;
+break;
 default:
 qemu_log_mask(LOG_UNIMP,
   "bcm2835_property: unhandled tag 0x%08x\n", tag);
diff --git a/include/hw/arm/raspberrypi-fw-defs.h 
b/include/hw/arm/raspberrypi-fw-defs.h
index 579cf0d554..8b404e0533 100644
--- a/include/hw/arm/raspberrypi-fw-defs.h
+++ b/include/hw/arm/raspberrypi-fw-defs.h
@@ -159,4 +159,15 @@ enum rpi_firmware_clk_id {
 RPI_FIRMWARE_NUM_CLK_ID,
 };
 
+struct rpi_firmware_property_tag_header {
+uint32_t tag;
+uint32_t buf_size;
+uint32_t req_resp_size;
+};
+
+typedef struct rpi_firmware_prop_request {
+struct rpi_firmware_property_tag_header hdr;
+uint8_t payload[0];
+} rpi_firmware_prop_request_t;
+
 #endif /* INCLUDE_HW_MISC_RASPBERRYPI_FW_DEFS_H_ */
-- 
2.34.1




[PATCH v6 12/41] Add memory region for BCM2837 RPiVid ASB

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
Reviewed-by: Peter Maydell 
---
 hw/arm/bcm2838_peripherals.c | 3 +++
 include/hw/arm/bcm2838_peripherals.h | 2 ++
 include/hw/arm/raspi_platform.h  | 2 +-
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/arm/bcm2838_peripherals.c b/hw/arm/bcm2838_peripherals.c
index 55ae56733f..ca2f37b260 100644
--- a/hw/arm/bcm2838_peripherals.c
+++ b/hw/arm/bcm2838_peripherals.c
@@ -185,6 +185,9 @@ static void bcm2838_peripherals_realize(DeviceState *dev, 
Error **errp)
 sysbus_mmio_get_region(SYS_BUS_DEVICE(>gpio), 0));
 
 object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(>gpio), "sd-bus");
+
+/* BCM2838 RPiVid ASB must be mapped to prevent kernel crash */
+create_unimp(s_base, >asb, "bcm2838-asb", BRDG_OFFSET, 0x24);
 }
 
 static void bcm2838_peripherals_class_init(ObjectClass *oc, void *data)
diff --git a/include/hw/arm/bcm2838_peripherals.h 
b/include/hw/arm/bcm2838_peripherals.h
index 86b0d96944..af085934c9 100644
--- a/include/hw/arm/bcm2838_peripherals.h
+++ b/include/hw/arm/bcm2838_peripherals.h
@@ -69,6 +69,8 @@ struct BCM2838PeripheralState {
 OrIRQState mmc_irq_orgate;
 OrIRQState dma_7_8_irq_orgate;
 OrIRQState dma_9_10_irq_orgate;
+
+UnimplementedDeviceState asb;
 };
 
 struct BCM2838PeripheralClass {
diff --git a/include/hw/arm/raspi_platform.h b/include/hw/arm/raspi_platform.h
index 0db146e592..7bc4807fa5 100644
--- a/include/hw/arm/raspi_platform.h
+++ b/include/hw/arm/raspi_platform.h
@@ -73,7 +73,7 @@ uint64_t board_ram_size(uint32_t board_rev);
 #define MPHI_OFFSET 0x6000   /* Message-based Parallel Host Intf. 
*/
 #define DMA_OFFSET  0x7000   /* DMA controller, channels 0-14 */
 #define ARBA_OFFSET 0x9000
-#define BRDG_OFFSET 0xa000
+#define BRDG_OFFSET 0xa000   /* RPiVid ASB for BCM2838 (BCM2711) */
 #define ARM_OFFSET  0xB000   /* ARM control block */
 #define ARMCTRL_OFFSET  (ARM_OFFSET + 0x000)
 #define ARMCTRL_IC_OFFSET   (ARM_OFFSET + 0x200) /* Interrupt controller */
-- 
2.34.1




[PATCH v6 11/41] Temporarily disable unimplemented rpi4b devices

2024-02-25 Thread Sergey Kambalin
This commit adds RPi4B device tree modifications:
- disable pcie, rng200, thermal sensor and genet devices
  (they're going to be re-enabled in the following commits)
- create additional memory region in device tree
  if RAM amount exceeds VC base address.

Signed-off-by: Sergey Kambalin 
Reviewed-by: Peter Maydell 
---
 hw/arm/raspi.c  |  5 +--
 hw/arm/raspi4b.c| 62 +
 include/hw/arm/raspi_platform.h |  4 +++
 3 files changed, 67 insertions(+), 4 deletions(-)

diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 8b1a046912..a7a662f40d 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -37,9 +37,6 @@ OBJECT_DECLARE_SIMPLE_TYPE(RaspiMachineState, RASPI_MACHINE)
 #define FIRMWARE_ADDR_3 0x8 /* Pi 3 loads kernel.img here by default */
 #define SPINTABLE_ADDR  0xd8 /* Pi 3 bootloader spintable */
 
-/* Registered machine type (matches RPi Foundation bootloader and U-Boot) */
-#define MACH_TYPE_BCM2708   3138
-
 struct RaspiMachineState {
 /*< private >*/
 RaspiBaseMachineState parent_obj;
@@ -75,7 +72,7 @@ static const struct {
 [PROCESSOR_ID_BCM2838] = {TYPE_BCM2838, BCM283X_NCPUS},
 };
 
-static uint64_t board_ram_size(uint32_t board_rev)
+uint64_t board_ram_size(uint32_t board_rev)
 {
 assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */
 return 256 * MiB << FIELD_EX32(board_rev, REV_CODE, MEMORY_SIZE);
diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c
index 36a4593928..49dec6e53a 100644
--- a/hw/arm/raspi4b.c
+++ b/hw/arm/raspi4b.c
@@ -21,6 +21,7 @@
 #include "hw/arm/boot.h"
 #include "qom/object.h"
 #include "hw/arm/bcm2838.h"
+#include 
 
 #define TYPE_RASPI4B_MACHINE MACHINE_TYPE_NAME("raspi4b-2g")
 OBJECT_DECLARE_SIMPLE_TYPE(Raspi4bMachineState, RASPI4B_MACHINE)
@@ -30,6 +31,66 @@ struct Raspi4bMachineState {
 BCM2838State soc;
 };
 
+/*
+ * Add second memory region if board RAM amount exceeds VC base address
+ * (see https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf
+ * 1.2 Address Map)
+ */
+static int raspi_add_memory_node(void *fdt, hwaddr mem_base, hwaddr mem_len)
+{
+int ret;
+uint32_t acells, scells;
+char *nodename = g_strdup_printf("/memory@%" PRIx64, mem_base);
+
+acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells",
+   NULL, _fatal);
+scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells",
+   NULL, _fatal);
+if (acells == 0 || scells == 0) {
+fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 
0)\n");
+ret = -1;
+} else {
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
+ret = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
+   acells, mem_base,
+   scells, mem_len);
+}
+
+g_free(nodename);
+return ret;
+}
+
+static void raspi4_modify_dtb(const struct arm_boot_info *info, void *fdt)
+{
+uint64_t ram_size;
+
+/* Temporarily disable following devices until they are implemented */
+const char *nodes_to_remove[] = {
+"brcm,bcm2711-pcie",
+"brcm,bcm2711-rng200",
+"brcm,bcm2711-thermal",
+"brcm,bcm2711-genet-v5",
+};
+
+for (int i = 0; i < ARRAY_SIZE(nodes_to_remove); i++) {
+const char *dev_str = nodes_to_remove[i];
+
+int offset = fdt_node_offset_by_compatible(fdt, -1, dev_str);
+if (offset >= 0) {
+if (!fdt_nop_node(fdt, offset)) {
+warn_report("bcm2711 dtc: %s has been disabled!", dev_str);
+}
+}
+}
+
+ram_size = board_ram_size(info->board_id);
+
+if (info->ram_size > UPPER_RAM_BASE) {
+raspi_add_memory_node(fdt, UPPER_RAM_BASE, ram_size - UPPER_RAM_BASE);
+}
+}
+
 static void raspi4b_machine_init(MachineState *machine)
 {
 Raspi4bMachineState *s = RASPI4B_MACHINE(machine);
@@ -37,6 +98,7 @@ static void raspi4b_machine_init(MachineState *machine)
 RaspiBaseMachineClass *mc = RASPI_BASE_MACHINE_GET_CLASS(machine);
 BCM2838State *soc = >soc;
 
+s_base->binfo.modify_dtb = raspi4_modify_dtb;
 s_base->binfo.board_id = mc->board_rev;
 
 object_initialize_child(OBJECT(machine), "soc", soc,
diff --git a/include/hw/arm/raspi_platform.h b/include/hw/arm/raspi_platform.h
index 45003e2425..0db146e592 100644
--- a/include/hw/arm/raspi_platform.h
+++ b/include/hw/arm/raspi_platform.h
@@ -31,6 +31,9 @@
 #include "hw/boards.h"
 #include "hw/arm/boot.h"
 
+/* Registered machine type (matches RPi Foundation bootloader and U-Boot) */
+#define MACH_TYPE_BCM2708   3138
+
 #define TYPE_RASPI_BASE_MACHINE MACHINE_TYPE_NAME("raspi-base")
 OBJECT_DECLARE_TYPE(RaspiBaseMachineState, RaspiBaseMachineClass,
 RASPI_BASE_MACHINE)
@@ -59,6 +62,7 @@ void raspi_base_machine_init(MachineState *machine,
 
 void 

[PATCH v6 20/41] Add GENET register structs. Part 1

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 hw/net/bcm2838_genet.c | 37 
 include/hw/net/bcm2838_genet.h | 77 +-
 2 files changed, 113 insertions(+), 1 deletion(-)

diff --git a/hw/net/bcm2838_genet.c b/hw/net/bcm2838_genet.c
index 4420486e00..0d98d1b30e 100644
--- a/hw/net/bcm2838_genet.c
+++ b/hw/net/bcm2838_genet.c
@@ -15,9 +15,46 @@
 #include "hw/irq.h"
 #include "net/checksum.h"
 #include "sysemu/dma.h"
+#include "hw/registerfields.h"
 #include "hw/net/bcm2838_genet.h"
 #include "trace.h"
 
+REG32(GENET_SYS_REV_CTRL,  0)
+FIELD(GENET_SYS_REV_CTRL, GPHY_REV,0, 16)
+FIELD(GENET_SYS_REV_CTRL, MINOR_REV,   16, 4)
+FIELD(GENET_SYS_REV_CTRL, RSVD_20_23,  20, 4)
+FIELD(GENET_SYS_REV_CTRL, MAJOR_REV,   24, 4)
+FIELD(GENET_SYS_REV_CTRL, RSVD_28_31,  28, 4)
+
+REG32(GENET_INTRL_0,0)
+FIELD(GENET_INTRL_0, SCB,   0, 1)
+FIELD(GENET_INTRL_0, EPHY,  1, 1)
+FIELD(GENET_INTRL_0, PHY_DET_R, 2, 1)
+FIELD(GENET_INTRL_0, PHY_DET_F, 3, 1)
+FIELD(GENET_INTRL_0, LINK_UP,   4, 1)
+FIELD(GENET_INTRL_0, LINK_DOWN, 5, 1)
+FIELD(GENET_INTRL_0, UMAC,  6, 1)
+FIELD(GENET_INTRL_0, UMAC_TSV,  7, 1)
+FIELD(GENET_INTRL_0, TBUF_UNDERRUN, 8, 1)
+FIELD(GENET_INTRL_0, RBUF_OVERFLOW, 9, 1)
+FIELD(GENET_INTRL_0, HFB_SM,10, 1)
+FIELD(GENET_INTRL_0, HFB_MM,11, 1)
+FIELD(GENET_INTRL_0, MPD_R, 12, 1)
+FIELD(GENET_INTRL_0, RXDMA_MBDONE,  13, 1)
+FIELD(GENET_INTRL_0, RXDMA_PDONE,   14, 1)
+FIELD(GENET_INTRL_0, RXDMA_BDONE,   15, 1)
+FIELD(GENET_INTRL_0, TXDMA_MBDONE,  16, 1)
+FIELD(GENET_INTRL_0, TXDMA_PDONE,   17, 1)
+FIELD(GENET_INTRL_0, TXDMA_BDONE,   18, 1)
+FIELD(GENET_INTRL_0, RSVD_19_22,19, 4)
+FIELD(GENET_INTRL_0, MDIO_DONE, 23, 1)
+FIELD(GENET_INTRL_0, MDIO_ERROR,24, 1)
+FIELD(GENET_INTRL_0, RSVD_25_31,25, 4)
+
+REG32(GENET_INTRL_1,  0)
+FIELD(GENET_INTRL_1, TX_INTRS,0, 16)
+FIELD(GENET_INTRL_1, RX_INTRS,16, 16)
+
 
 static uint64_t bcm2838_genet_read(void *opaque, hwaddr offset, unsigned size)
 {
diff --git a/include/hw/net/bcm2838_genet.h b/include/hw/net/bcm2838_genet.h
index d166a5c24c..f583818399 100644
--- a/include/hw/net/bcm2838_genet.h
+++ b/include/hw/net/bcm2838_genet.h
@@ -19,7 +19,82 @@ OBJECT_DECLARE_SIMPLE_TYPE(BCM2838GenetState, BCM2838_GENET)
 #define BCM2838_GENET_REV_MINOR 0
 
 typedef struct {
-uint8_t stub_area[0x1]; /* temporary stub */
+uint32_t rev_ctrl;
+uint32_t port_ctrl;
+uint32_t rbuf_flush_ctrl;
+uint32_t tbuf_flush_ctrl;
+uint32_t reserved_0x10[12];
+} BCM2838GenetRegsSys;
+
+typedef struct {
+uint32_t reserved_0x0[16];
+} BCM2838GenetRegsGrBridge;
+
+typedef struct {
+uint32_t pwr_mgmt;
+uint32_t reserved_0x4[2];
+uint32_t rgmii_oob_ctrl;
+uint32_t reserved_0x10[3];
+uint32_t gphy_ctrl;
+uint32_t reserved_0x20[24];
+} BCM2838GenetRegsExt;
+
+typedef struct {
+uint32_t stat;
+uint32_t set;
+uint32_t clear;
+uint32_t mask_status;
+uint32_t mask_set;
+uint32_t mask_clear;
+uint32_t reserved_0x18[10];
+} BCM2838GenetRegsIntrl0;
+
+typedef struct {
+uint32_t stat;
+uint32_t set;
+uint32_t clear;
+uint32_t mask_status;
+uint32_t mask_set;
+uint32_t mask_clear;
+uint32_t reserved_0x18[10];
+} BCM2838GenetRegsIntrl1;
+
+typedef struct {
+uint32_t ctrl;
+uint32_t reserved_0x4[2];
+uint32_t status;
+uint32_t reserved_0x10;
+uint32_t chk_ctrl;
+uint32_t reserved_0x18[31];
+uint32_t ovfl_cnt;
+uint32_t err_cnt;
+uint32_t energy_ctrl;
+uint32_t reserved_0xA0[5];
+uint32_t size_ctrl;
+uint32_t reserved_0xB8[18];
+} BCM2838GenetRegsRbuf;
+
+typedef struct {
+uint32_t ctrl;
+uint32_t reserved_0x4[2];
+uint32_t bp_mc;
+uint32_t reserved_0x10;
+uint32_t energy_ctrl;
+uint32_t reserved_0x18[58];
+} BCM2838GenetRegsTbuf;
+
+typedef struct {
+BCM2838GenetRegsSys sys;
+BCM2838GenetRegsGrBridge gr_bridge;
+BCM2838GenetRegsExt ext;
+uint32_t reserved_0x100[64];
+BCM2838GenetRegsIntrl0 intrl0;
+BCM2838GenetRegsIntrl1 intrl1;
+uint32_t reserved_0x280[32];
+BCM2838GenetRegsRbuf rbuf;
+uint32_t reserved_0x400[128];
+BCM2838GenetRegsTbuf tbuf;
+uint32_t reserved_0x700[64];
 } BCM2838GenetRegs;
 
 struct BCM2838GenetState {
-- 
2.34.1




[PATCH v6 27/41] Implement GENET TX path

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 hw/net/bcm2838_genet.c | 221 -
 include/hw/net/bcm2838_genet.h |  17 +++
 2 files changed, 237 insertions(+), 1 deletion(-)

diff --git a/hw/net/bcm2838_genet.c b/hw/net/bcm2838_genet.c
index 1fae3ecbc2..4c9b39a3ca 100644
--- a/hw/net/bcm2838_genet.c
+++ b/hw/net/bcm2838_genet.c
@@ -234,6 +234,13 @@ REG16(GENET_PHY_EXP_SEL,   0)
 FIELD(GENET_PHY_EXP_SEL, REG_ID,   0, 8)
 FIELD(GENET_PHY_EXP_SEL, BLOCK_ID, 8, 8)
 
+REG32(GENET_TX_CSUM_INFO,0)
+FIELD(GENET_TX_CSUM_INFO, OFFSET,0, 15)
+FIELD(GENET_TX_CSUM_INFO, PROTO_UDP, 15, 1)
+FIELD(GENET_TX_CSUM_INFO, START, 16, 15)
+FIELD(GENET_TX_CSUM_INFO, LV,30, 1)
+
+
 static void bcm2838_genet_set_qemu_mac(BCM2838GenetState *s)
 {
 const MACAddr *addr = >nic_conf.macaddr;
@@ -387,6 +394,218 @@ static uint64_t bcm2838_genet_mdio_cmd(BCM2838GenetState 
*s, uint64_t cmd)
 return cmd;
 }
 
+static void bcm2838_genet_xmit_packet(NetClientState *s, void *packet,
+  size_t size)
+{
+uint8_t *buf = packet + sizeof(BCM2838GenetXmitStatus);
+size_t len = size;
+uint16_t len_type = 0;
+
+len -= sizeof(BCM2838GenetXmitStatus);
+net_checksum_calculate(buf, len, CSUM_ALL);
+
+memcpy(_type, [12], sizeof(len_type));
+len_type = ntohs(len_type);
+if (len_type < MAX_PAYLOAD_SIZE) {
+len_type = len;
+len_type = htons(len_type);
+memcpy([12], _type, sizeof(len_type));
+}
+
+qemu_send_packet(s, buf, len);
+}
+
+static uint64_t bcm2838_genet_tx(BCM2838GenetState *s, unsigned int ring_index,
+ uint32_t prod_index,
+ uint32_t cons_index)
+{
+const unsigned int DESC_SIZE_WORDS
+= sizeof(BCM2838GenetTdmaDesc) / sizeof(uint32_t);
+const uint64_t RING_START_ADDR
+= ((uint64_t)s->regs.tdma.rings[ring_index].start_addr_hi << 32)
++ s->regs.tdma.rings[ring_index].start_addr;
+const uint64_t RING_END_ADDR
+= ((uint64_t)s->regs.tdma.rings[ring_index].end_addr_hi << 32)
++ s->regs.tdma.rings[ring_index].end_addr;
+
+hwaddr data_addr;
+uint64_t desc_index;
+uint32_t desc_status = 0;
+uint32_t buflength = 0;
+uint64_t num_descs = 0;
+uint64_t read_ptr
+= ((uint64_t)s->regs.tdma.rings[ring_index].read_ptr_hi << 32)
++ s->regs.tdma.rings[ring_index].read_ptr;
+off_t packet_off = 0;
+
+uint32_t prod_index_fld = FIELD_EX32(prod_index,
+ GENET_DMA_PROD_INDEX, INDEX);
+uint32_t cons_index_fld = FIELD_EX32(cons_index,
+GENET_DMA_CONS_INDEX, INDEX);
+
+while (cons_index_fld != prod_index_fld) {
+desc_index = read_ptr / DESC_SIZE_WORDS;
+if (desc_index >= BCM2838_GENET_DMA_DESC_CNT) {
+qemu_log_mask(
+LOG_GUEST_ERROR,
+"%s: invalid TX descriptor index %" PRIu64 " (exceeds %u)\n",
+__func__, desc_index, BCM2838_GENET_DMA_DESC_CNT - 1);
+break;
+}
+desc_status = s->regs.tdma.descs[desc_index].length_status;
+data_addr = ((uint64_t)s->regs.tdma.descs[desc_index].address_hi << 32)
++ s->regs.tdma.descs[desc_index].address_lo;
+trace_bcm2838_genet_tx(ring_index, desc_index, desc_status,
+   data_addr);
+
+if (FIELD_EX32(desc_status, GENET_RDMA_LENGTH_STATUS, SOP) != 0) {
+packet_off = 0;
+}
+
+buflength = FIELD_EX32(desc_status,
+   GENET_RDMA_LENGTH_STATUS, BUFLENGTH);
+
+/* TODO: Add address_space_read() return value check */
+address_space_read(>dma_as, data_addr,
+MEMTXATTRS_UNSPECIFIED,
+s->tx_packet + packet_off,
+buflength);
+packet_off += buflength;
+
+if (FIELD_EX32(desc_status, GENET_RDMA_LENGTH_STATUS, EOP) != 0) {
+bcm2838_genet_xmit_packet(qemu_get_queue(s->nic), s->tx_packet,
+ packet_off);
+packet_off = 0;
+}
+
+num_descs++;
+cons_index_fld++;
+s->regs.tdma.descs[desc_index].length_status =
+FIELD_DP32(s->regs.tdma.descs[desc_index].length_status,
+   GENET_RDMA_LENGTH_STATUS, OWN, 1);
+read_ptr = read_ptr == RING_END_ADDR + 1 - DESC_SIZE_WORDS
+? RING_START_ADDR : read_ptr + DESC_SIZE_WORDS;
+}
+
+s->regs.tdma.rings[ring_index].read_ptr = read_ptr;
+s->regs.tdma.rings[ring_index].read_ptr_hi = read_ptr >> 32;
+
+return num_descs;
+}
+
+static bool bcm2838_genet_tdma_ring_active(BCM2838GenetState *s,
+   unsigned int ring_index)
+{
+

[PATCH v6 23/41] Add GENET register structs. Part 4

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 include/hw/net/bcm2838_genet.h | 37 ++
 1 file changed, 37 insertions(+)

diff --git a/include/hw/net/bcm2838_genet.h b/include/hw/net/bcm2838_genet.h
index 1bd004785a..94c2f3ebca 100644
--- a/include/hw/net/bcm2838_genet.h
+++ b/include/hw/net/bcm2838_genet.h
@@ -25,6 +25,12 @@ OBJECT_DECLARE_SIMPLE_TYPE(BCM2838GenetState, BCM2838_GENET)
 #define BCM2838_GENET_HFB_FILTER_CNT  48
 #define BCM2838_GENET_HFB_FILTER_SIZE 128
 
+#define BCM2838_GENET_PHY_AUX_CTL_MISC  0x7
+#define BCM2838_GENET_PHY_AUX_CTL_REGS_SIZE 8
+
+#define BCM2838_GENET_PHY_EXP_SHD_BLOCKS_CNT 256
+#define BCM2838_GENET_PHY_EXP_SHD_REGS_CNT   256
+
 typedef struct {
 uint32_t rev_ctrl;
 uint32_t port_ctrl;
@@ -273,6 +279,34 @@ typedef struct {
 uint16_t rdb_data;
 } BCM2838GenetPhyRegs;
 
+typedef struct {
+uint16_t reserved_0_2[3];
+uint16_t clk_ctl;
+uint16_t scr2;
+uint16_t scr3;
+uint16_t reserved_6_9[4];
+uint16_t apd;
+uint16_t rgmii_mode;
+uint16_t reserved_12;
+uint16_t leds1;
+uint16_t reserved_14_18[5];
+uint16_t _100fx_ctrl;
+uint16_t ssd;
+uint16_t reserved_21_30[10];
+uint16_t mode;
+} BCM2838GenetPhyShdRegs;
+
+typedef struct {
+uint16_t auxctl;
+uint16_t reserved_1_6[BCM2838_GENET_PHY_AUX_CTL_REGS_SIZE - 2];
+uint16_t misc;
+} BCM2838GenetPhyAuxShdRegs;
+
+typedef struct {
+uint16_t regs[BCM2838_GENET_PHY_EXP_SHD_BLOCKS_CNT]
+ [BCM2838_GENET_PHY_EXP_SHD_REGS_CNT];
+} BCM2838GenetPhyExpShdRegs;
+
 struct BCM2838GenetState {
 /*< private >*/
 SysBusDevice parent_obj;
@@ -284,6 +318,9 @@ struct BCM2838GenetState {
 
 BCM2838GenetRegs regs;
 BCM2838GenetPhyRegs phy_regs;
+BCM2838GenetPhyShdRegs phy_shd_regs;
+BCM2838GenetPhyAuxShdRegs phy_aux_ctl_shd_regs;
+BCM2838GenetPhyExpShdRegs phy_exp_shd_regs;
 
 qemu_irq irq_default;
 qemu_irq irq_prio;
-- 
2.34.1




Re: [PATCH v6 2/3] hw/arm: Connect STM32L4x5 GPIO to STM32L4x5 SoC

2024-02-25 Thread Alistair Francis
On Sat, Feb 24, 2024 at 8:56 PM Inès Varhol
 wrote:
>
> Signed-off-by: Arnaud Minier 
> Signed-off-by: Inès Varhol 
> Reviewed-by: Philippe Mathieu-Daudé 

Acked-by: Alistair Francis 

Alistair

> ---
>  include/hw/arm/stm32l4x5_soc.h |  2 +
>  include/hw/gpio/stm32l4x5_gpio.h   |  1 +
>  include/hw/misc/stm32l4x5_syscfg.h |  3 +-
>  hw/arm/stm32l4x5_soc.c | 71 +++---
>  hw/misc/stm32l4x5_syscfg.c |  1 +
>  hw/arm/Kconfig |  3 +-
>  6 files changed, 63 insertions(+), 18 deletions(-)
>
> diff --git a/include/hw/arm/stm32l4x5_soc.h b/include/hw/arm/stm32l4x5_soc.h
> index 1f71298b45..cb4da08629 100644
> --- a/include/hw/arm/stm32l4x5_soc.h
> +++ b/include/hw/arm/stm32l4x5_soc.h
> @@ -29,6 +29,7 @@
>  #include "hw/misc/stm32l4x5_syscfg.h"
>  #include "hw/misc/stm32l4x5_exti.h"
>  #include "hw/misc/stm32l4x5_rcc.h"
> +#include "hw/gpio/stm32l4x5_gpio.h"
>  #include "qom/object.h"
>
>  #define TYPE_STM32L4X5_SOC "stm32l4x5-soc"
> @@ -45,6 +46,7 @@ struct Stm32l4x5SocState {
>  Stm32l4x5ExtiState exti;
>  Stm32l4x5SyscfgState syscfg;
>  Stm32l4x5RccState rcc;
> +Stm32l4x5GpioState gpio[NUM_GPIOS];
>
>  MemoryRegion sram1;
>  MemoryRegion sram2;
> diff --git a/include/hw/gpio/stm32l4x5_gpio.h 
> b/include/hw/gpio/stm32l4x5_gpio.h
> index 0d361f3410..878bd19fc9 100644
> --- a/include/hw/gpio/stm32l4x5_gpio.h
> +++ b/include/hw/gpio/stm32l4x5_gpio.h
> @@ -25,6 +25,7 @@
>  #define TYPE_STM32L4X5_GPIO "stm32l4x5-gpio"
>  OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5GpioState, STM32L4X5_GPIO)
>
> +#define NUM_GPIOS 8
>  #define GPIO_NUM_PINS 16
>
>  struct Stm32l4x5GpioState {
> diff --git a/include/hw/misc/stm32l4x5_syscfg.h 
> b/include/hw/misc/stm32l4x5_syscfg.h
> index 29c3522f9d..23bb564150 100644
> --- a/include/hw/misc/stm32l4x5_syscfg.h
> +++ b/include/hw/misc/stm32l4x5_syscfg.h
> @@ -26,12 +26,11 @@
>
>  #include "hw/sysbus.h"
>  #include "qom/object.h"
> +#include "hw/gpio/stm32l4x5_gpio.h"
>
>  #define TYPE_STM32L4X5_SYSCFG "stm32l4x5-syscfg"
>  OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5SyscfgState, STM32L4X5_SYSCFG)
>
> -#define NUM_GPIOS 8
> -#define GPIO_NUM_PINS 16
>  #define SYSCFG_NUM_EXTICR 4
>
>  struct Stm32l4x5SyscfgState {
> diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
> index 347a5377e5..072671bdfb 100644
> --- a/hw/arm/stm32l4x5_soc.c
> +++ b/hw/arm/stm32l4x5_soc.c
> @@ -27,6 +27,7 @@
>  #include "exec/address-spaces.h"
>  #include "sysemu/sysemu.h"
>  #include "hw/arm/stm32l4x5_soc.h"
> +#include "hw/gpio/stm32l4x5_gpio.h"
>  #include "hw/qdev-clock.h"
>  #include "hw/misc/unimp.h"
>
> @@ -78,6 +79,22 @@ static const int exti_irq[NUM_EXTI_IRQ] = {
>  #define RCC_BASE_ADDRESS 0x40021000
>  #define RCC_IRQ 5
>
> +static const struct {
> +uint32_t addr;
> +uint32_t moder_reset;
> +uint32_t ospeedr_reset;
> +uint32_t pupdr_reset;
> +} stm32l4x5_gpio_cfg[NUM_GPIOS] = {
> +{ 0x4800, 0xABFF, 0x0C00, 0x6400 },
> +{ 0x48000400, 0xFEBF, 0x, 0x0100 },
> +{ 0x48000800, 0x, 0x, 0x },
> +{ 0x48000C00, 0x, 0x, 0x },
> +{ 0x48001000, 0x, 0x, 0x },
> +{ 0x48001400, 0x, 0x, 0x },
> +{ 0x48001800, 0x, 0x, 0x },
> +{ 0x48001C00, 0x000F, 0x, 0x },
> +};
> +
>  static void stm32l4x5_soc_initfn(Object *obj)
>  {
>  Stm32l4x5SocState *s = STM32L4X5_SOC(obj);
> @@ -85,6 +102,11 @@ static void stm32l4x5_soc_initfn(Object *obj)
>  object_initialize_child(obj, "exti", >exti, TYPE_STM32L4X5_EXTI);
>  object_initialize_child(obj, "syscfg", >syscfg, 
> TYPE_STM32L4X5_SYSCFG);
>  object_initialize_child(obj, "rcc", >rcc, TYPE_STM32L4X5_RCC);
> +
> +for (unsigned i = 0; i < NUM_GPIOS; i++) {
> +g_autofree char *name = g_strdup_printf("gpio%c", 'a' + i);
> +object_initialize_child(obj, name, >gpio[i], TYPE_STM32L4X5_GPIO);
> +}
>  }
>
>  static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
> @@ -93,8 +115,9 @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, 
> Error **errp)
>  Stm32l4x5SocState *s = STM32L4X5_SOC(dev_soc);
>  const Stm32l4x5SocClass *sc = STM32L4X5_SOC_GET_CLASS(dev_soc);
>  MemoryRegion *system_memory = get_system_memory();
> -DeviceState *armv7m;
> +DeviceState *armv7m, *dev;
>  SysBusDevice *busdev;
> +uint32_t pin_index;
>
>  if (!memory_region_init_rom(>flash, OBJECT(dev_soc), "flash",
>  sc->flash_size, errp)) {
> @@ -135,17 +158,43 @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, 
> Error **errp)
>  return;
>  }
>
> +/* GPIOs */
> +for (unsigned i = 0; i < NUM_GPIOS; i++) {
> +g_autofree char *name = g_strdup_printf("%c", 'A' + i);
> +dev = DEVICE(>gpio[i]);
> +qdev_prop_set_string(dev, "name", name);
> +

Re: [PATCH v6 1/3] hw/gpio: Implement STM32L4x5 GPIO

2024-02-25 Thread Alistair Francis
On Sat, Feb 24, 2024 at 8:55 PM Inès Varhol
 wrote:
>
> Features supported :
> - the 8 STM32L4x5 GPIOs are initialized with their reset values
> (except IDR, see below)
> - input mode : setting a pin in input mode "externally" (using input
> irqs) results in an out irq (transmitted to SYSCFG)
> - output mode : setting a bit in ODR sets the corresponding out irq
> (if this line is configured in output mode)
> - pull-up, pull-down
> - push-pull, open-drain
>
> Difference with the real GPIOs :
> - Alternate Function and Analog mode aren't implemented :
> pins in AF/Analog behave like pins in input mode
> - floating pins stay at their last value
> - register IDR reset values differ from the real one :
> values are coherent with the other registers reset values
> and the fact that AF/Analog modes aren't implemented
> - setting I/O output speed isn't supported
> - locking port bits isn't supported
> - ADC function isn't supported
> - GPIOH has 16 pins instead of 2 pins
> - writing to registers LCKR, AFRL, AFRH and ASCR is ineffective
>
> Signed-off-by: Arnaud Minier 
> Signed-off-by: Inès Varhol 
> Reviewed-by: Philippe Mathieu-Daudé 

Acked-by: Alistair Francis 

Alistair

> ---
>  MAINTAINERS|   1 +
>  docs/system/arm/b-l475e-iot01a.rst |   2 +-
>  include/hw/gpio/stm32l4x5_gpio.h   |  70 +
>  hw/gpio/stm32l4x5_gpio.c   | 477 +
>  hw/gpio/Kconfig|   3 +
>  hw/gpio/meson.build|   1 +
>  hw/gpio/trace-events   |   6 +
>  7 files changed, 559 insertions(+), 1 deletion(-)
>  create mode 100644 include/hw/gpio/stm32l4x5_gpio.h
>  create mode 100644 hw/gpio/stm32l4x5_gpio.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 50ab2982bb..cf49c151f3 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1131,6 +1131,7 @@ F: hw/arm/stm32l4x5_soc.c
>  F: hw/misc/stm32l4x5_exti.c
>  F: hw/misc/stm32l4x5_syscfg.c
>  F: hw/misc/stm32l4x5_rcc.c
> +F: hw/gpio/stm32l4x5_gpio.c
>  F: include/hw/*/stm32l4x5_*.h
>
>  B-L475E-IOT01A IoT Node
> diff --git a/docs/system/arm/b-l475e-iot01a.rst 
> b/docs/system/arm/b-l475e-iot01a.rst
> index b857a56ca4..0afef8e4f4 100644
> --- a/docs/system/arm/b-l475e-iot01a.rst
> +++ b/docs/system/arm/b-l475e-iot01a.rst
> @@ -18,6 +18,7 @@ Currently B-L475E-IOT01A machine's only supports the 
> following devices:
>  - STM32L4x5 EXTI (Extended interrupts and events controller)
>  - STM32L4x5 SYSCFG (System configuration controller)
>  - STM32L4x5 RCC (Reset and clock control)
> +- STM32L4x5 GPIOs (General-purpose I/Os)
>
>  Missing devices
>  """
> @@ -25,7 +26,6 @@ Missing devices
>  The B-L475E-IOT01A does *not* support the following devices:
>
>  - Serial ports (UART)
> -- General-purpose I/Os (GPIO)
>  - Analog to Digital Converter (ADC)
>  - SPI controller
>  - Timer controller (TIMER)
> diff --git a/include/hw/gpio/stm32l4x5_gpio.h 
> b/include/hw/gpio/stm32l4x5_gpio.h
> new file mode 100644
> index 00..0d361f3410
> --- /dev/null
> +++ b/include/hw/gpio/stm32l4x5_gpio.h
> @@ -0,0 +1,70 @@
> +/*
> + * STM32L4x5 GPIO (General Purpose Input/Ouput)
> + *
> + * Copyright (c) 2024 Arnaud Minier 
> + * Copyright (c) 2024 Inès Varhol 
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +/*
> + * The reference used is the STMicroElectronics RM0351 Reference manual
> + * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
> + * 
> https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
> + */
> +
> +#ifndef HW_STM32L4X5_GPIO_H
> +#define HW_STM32L4X5_GPIO_H
> +
> +#include "hw/sysbus.h"
> +#include "qom/object.h"
> +
> +#define TYPE_STM32L4X5_GPIO "stm32l4x5-gpio"
> +OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5GpioState, STM32L4X5_GPIO)
> +
> +#define GPIO_NUM_PINS 16
> +
> +struct Stm32l4x5GpioState {
> +SysBusDevice parent_obj;
> +
> +MemoryRegion mmio;
> +
> +/* GPIO registers */
> +uint32_t moder;
> +uint32_t otyper;
> +uint32_t ospeedr;
> +uint32_t pupdr;
> +uint32_t idr;
> +uint32_t odr;
> +uint32_t lckr;
> +uint32_t afrl;
> +uint32_t afrh;
> +uint32_t ascr;
> +
> +/* GPIO registers reset values */
> +uint32_t moder_reset;
> +uint32_t ospeedr_reset;
> +uint32_t pupdr_reset;
> +
> +/*
> + * External driving of pins.
> + * The pins can be set externally through the device
> + * anonymous input GPIOs lines under certain conditions.
> + * The pin must not be in push-pull output mode,
> + * and can't be set high in open-drain mode.
> + * Pins driven externally and configured to
> + * output mode will in general be "disconnected"
> + * (see `get_gpio_pinmask_to_disconnect()`)
> + */
> +uint16_t disconnected_pins;
> +uint16_t pins_connected_high;
> +
> +   

[PATCH v6 33/41] Add mailbox tests tags. Part 1

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 tests/qtest/bcm2838-mailbox.h | 177 ++
 1 file changed, 177 insertions(+)

diff --git a/tests/qtest/bcm2838-mailbox.h b/tests/qtest/bcm2838-mailbox.h
index 9222b38bad..1360fbb8cf 100644
--- a/tests/qtest/bcm2838-mailbox.h
+++ b/tests/qtest/bcm2838-mailbox.h
@@ -116,6 +116,183 @@ typedef struct {  
  \
 };  \
 } TypeName
 
+DECLARE_TAG_TYPE(TAG_GET_FIRMWARE_REVISION_t,
+struct {},
+struct {
+uint32_t revision;
+});
+
+DECLARE_TAG_TYPE(TAG_GET_FIRMWARE_VARIANT_t,
+struct {},
+struct {
+uint32_t variant;
+});
+
+DECLARE_TAG_TYPE(TAG_GET_BOARD_REVISION_t,
+struct {},
+struct {
+uint32_t revision;
+});
+
+DECLARE_TAG_TYPE(TAG_GET_ARM_MEMORY_t,
+struct {},
+struct {
+uint32_t base;
+uint32_t size;
+});
+
+DECLARE_TAG_TYPE(TAG_GET_VC_MEMORY_t,
+struct {},
+struct {
+uint32_t base;
+uint32_t size;
+});
+
+DECLARE_TAG_TYPE(TAG_SET_POWER_STATE_t,
+struct {
+uint32_t device_id;
+uint32_t cmd;
+},
+struct {
+uint32_t device_id;
+uint32_t cmd;
+});
+
+DECLARE_TAG_TYPE(TAG_GET_CLOCK_STATE_t,
+struct {
+uint32_t clock_id;
+},
+struct {
+uint32_t clock_id;
+uint32_t cmd;
+});
+
+DECLARE_TAG_TYPE(TAG_GET_CLOCK_RATE_t,
+struct {
+uint32_t clock_id;
+},
+struct {
+uint32_t clock_id;
+uint32_t rate;
+});
+
+DECLARE_TAG_TYPE(TAG_GET_MAX_CLOCK_RATE_t,
+struct {
+uint32_t clock_id;
+},
+struct {
+uint32_t clock_id;
+uint32_t rate;
+});
+
+DECLARE_TAG_TYPE(TAG_GET_MIN_CLOCK_RATE_t,
+struct {
+uint32_t clock_id;
+},
+struct {
+uint32_t clock_id;
+uint32_t rate;
+});
+
+DECLARE_TAG_TYPE(TAG_GET_CLOCKS_t,
+struct {},
+struct {
+uint32_t root_clock;
+uint32_t arm_clock;
+});
+
+DECLARE_TAG_TYPE(TAG_GET_TEMPERATURE_t,
+struct {
+uint32_t temperature_id;
+},
+struct {
+uint32_t temperature_id;
+uint32_t temperature;
+});
+
+DECLARE_TAG_TYPE(TAG_GET_MAX_TEMPERATURE_t,
+struct {
+uint32_t temperature_id;
+},
+struct {
+uint32_t temperature_id;
+uint32_t temperature;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_ALLOCATE_t,
+struct {
+uint32_t alignment;
+},
+struct {
+uint32_t base;
+uint32_t size;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_RELEASE_t,
+struct {},
+struct {});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_BLANK_t,
+struct {
+uint32_t on;
+},
+struct {
+uint32_t on;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT_t,
+struct {},
+struct {
+uint32_t width;
+uint32_t height;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT_t,
+struct {
+uint32_t width;
+uint32_t height;
+},
+struct {
+uint32_t width;
+uint32_t height;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT_t,
+struct {
+uint32_t width;
+uint32_t height;
+},
+struct {
+uint32_t width;
+uint32_t height;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_VIRTUAL_WIDTH_HEIGHT_t,
+struct {},
+struct {
+uint32_t width;
+uint32_t height;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT_t,
+struct {
+uint32_t width;
+uint32_t height;
+},
+struct {
+uint32_t width;
+uint32_t height;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT_t,
+struct {
+uint32_t width;
+uint32_t height;
+},
+struct {
+uint32_t width;
+uint32_t height;
+});
 
 int mbox0_has_data(void);
 void mbox0_read_message(uint8_t channel, void *msgbuf, size_t msgbuf_size);
-- 
2.34.1




[PATCH v6 06/41] Add BCM2838 GPIO stub

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
Reviewed-by: Peter Maydell 
---
 hw/gpio/bcm2838_gpio.c | 153 +
 hw/gpio/meson.build|   5 +-
 include/hw/gpio/bcm2838_gpio.h |  40 +
 3 files changed, 197 insertions(+), 1 deletion(-)
 create mode 100644 hw/gpio/bcm2838_gpio.c
 create mode 100644 include/hw/gpio/bcm2838_gpio.h

diff --git a/hw/gpio/bcm2838_gpio.c b/hw/gpio/bcm2838_gpio.c
new file mode 100644
index 00..a312490bbd
--- /dev/null
+++ b/hw/gpio/bcm2838_gpio.c
@@ -0,0 +1,153 @@
+/*
+ * Raspberry Pi (BCM2838) GPIO Controller
+ * This implementation is based on bcm2835_gpio (hw/gpio/bcm2835_gpio.c)
+ *
+ * Copyright (c) 2022 Auriga LLC
+ *
+ * Authors:
+ *  Lotosh, Aleksey 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "qapi/error.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "hw/gpio/bcm2838_gpio.h"
+
+#define GPFSEL0   0x00
+#define GPFSEL1   0x04
+#define GPFSEL2   0x08
+#define GPFSEL3   0x0C
+#define GPFSEL4   0x10
+#define GPFSEL5   0x14
+#define GPSET00x1C
+#define GPSET10x20
+#define GPCLR00x28
+#define GPCLR10x2C
+#define GPLEV00x34
+#define GPLEV10x38
+#define GPEDS00x40
+#define GPEDS10x44
+#define GPREN00x4C
+#define GPREN10x50
+#define GPFEN00x58
+#define GPFEN10x5C
+#define GPHEN00x64
+#define GPHEN10x68
+#define GPLEN00x70
+#define GPLEN10x74
+#define GPAREN0   0x7C
+#define GPAREN1   0x80
+#define GPAFEN0   0x88
+#define GPAFEN1   0x8C
+
+#define GPIO_PUP_PDN_CNTRL_REG0 0xE4
+#define GPIO_PUP_PDN_CNTRL_REG1 0xE8
+#define GPIO_PUP_PDN_CNTRL_REG2 0xEC
+#define GPIO_PUP_PDN_CNTRL_REG3 0xF0
+
+#define RESET_VAL_CNTRL_REG0 0xAAA9
+#define RESET_VAL_CNTRL_REG1 0xA0AA
+#define RESET_VAL_CNTRL_REG2 0x50AAA95A
+#define RESET_VAL_CNTRL_REG3 0x0005
+
+#define BYTES_IN_WORD4
+
+static uint64_t bcm2838_gpio_read(void *opaque, hwaddr offset, unsigned size)
+{
+uint64_t value = 0;
+
+qemu_log_mask(LOG_UNIMP, "%s: %s: not implemented for %"HWADDR_PRIx"\n",
+  TYPE_BCM2838_GPIO, __func__, offset);
+
+return value;
+}
+
+static void bcm2838_gpio_write(void *opaque, hwaddr offset, uint64_t value,
+   unsigned size)
+{
+qemu_log_mask(LOG_UNIMP, "%s: %s: not implemented for %"HWADDR_PRIx"\n",
+  TYPE_BCM2838_GPIO, __func__, offset);
+}
+
+static void bcm2838_gpio_reset(DeviceState *dev)
+{
+BCM2838GpioState *s = BCM2838_GPIO(dev);
+
+s->lev0 = 0;
+s->lev1 = 0;
+
+memset(s->fsel, 0, sizeof(s->fsel));
+
+s->pup_cntrl_reg[0] = RESET_VAL_CNTRL_REG0;
+s->pup_cntrl_reg[1] = RESET_VAL_CNTRL_REG1;
+s->pup_cntrl_reg[2] = RESET_VAL_CNTRL_REG2;
+s->pup_cntrl_reg[3] = RESET_VAL_CNTRL_REG3;
+}
+
+static const MemoryRegionOps bcm2838_gpio_ops = {
+.read = bcm2838_gpio_read,
+.write = bcm2838_gpio_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription vmstate_bcm2838_gpio = {
+.name = "bcm2838_gpio",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT8_ARRAY(fsel, BCM2838GpioState, BCM2838_GPIO_NUM),
+VMSTATE_UINT32(lev0, BCM2838GpioState),
+VMSTATE_UINT32(lev1, BCM2838GpioState),
+VMSTATE_UINT8(sd_fsel, BCM2838GpioState),
+VMSTATE_UINT32_ARRAY(pup_cntrl_reg, BCM2838GpioState,
+ GPIO_PUP_PDN_CNTRL_NUM),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static void bcm2838_gpio_init(Object *obj)
+{
+BCM2838GpioState *s = BCM2838_GPIO(obj);
+DeviceState *dev = DEVICE(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+memory_region_init_io(>iomem, obj, _gpio_ops, s,
+  "bcm2838_gpio", BCM2838_GPIO_REGS_SIZE);
+sysbus_init_mmio(sbd, >iomem);
+qdev_init_gpio_out(dev, s->out, BCM2838_GPIO_NUM);
+}
+
+static void bcm2838_gpio_realize(DeviceState *dev, Error **errp)
+{
+/* Temporary stub. Do nothing */
+}
+
+static void bcm2838_gpio_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->vmsd = _bcm2838_gpio;
+dc->realize = _gpio_realize;
+dc->reset = _gpio_reset;
+}
+
+static const TypeInfo bcm2838_gpio_info = {
+.name  = TYPE_BCM2838_GPIO,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(BCM2838GpioState),
+.instance_init = bcm2838_gpio_init,
+.class_init= bcm2838_gpio_class_init,
+};
+
+static void bcm2838_gpio_register_types(void)
+{
+type_register_static(_gpio_info);
+}
+
+type_init(bcm2838_gpio_register_types)
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
index 066ea96480..8a8d03d885 100644
--- a/hw/gpio/meson.build
+++ b/hw/gpio/meson.build
@@ -9,6 +9,9 @@ system_ss.add(when: 'CONFIG_IMX', if_true: files('imx_gpio.c'))
 

[PATCH v6 40/41] Append added properties to mailbox test

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 tests/qtest/bcm2838-mbox-property-test.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/tests/qtest/bcm2838-mbox-property-test.c 
b/tests/qtest/bcm2838-mbox-property-test.c
index c96a9ba3f3..ff7c347e7c 100644
--- a/tests/qtest/bcm2838-mbox-property-test.c
+++ b/tests/qtest/bcm2838-mbox-property-test.c
@@ -270,6 +270,12 @@ DECLARE_TEST_CASE_SETUP(GET_MIN_CLOCK_RATE, ANY) {
 tag->request.value.clock_id = CLOCK_ID_UNDEFINED;
 }
 
+/**/
+DECLARE_TEST_CASE(GET_CLOCKS) {
+g_assert_cmphex(tag->response.value.root_clock, ==, CLOCK_ID_ROOT);
+g_assert_cmphex(tag->response.value.arm_clock, ==, CLOCK_ID_ARM);
+}
+
 
/**/
 DECLARE_TEST_CASE(GET_TEMPERATURE) {
 g_assert_cmphex(tag->response.value.temperature_id, ==, 
TEMPERATURE_ID_SOC);
@@ -536,6 +542,11 @@ DECLARE_TEST_CASE(GET_COMMAND_LINE) {
 /* No special checks are needed for this test case */
 }
 
+/**/
+DECLARE_TEST_CASE(GET_THROTTLED) {
+g_assert_cmpint(tag->response.value.throttled, ==, 0);
+}
+
 
/**/
 DECLARE_TEST_CASE(FRAMEBUFFER_GET_NUM_DISPLAYS) {
 g_assert_cmpint(tag->response.value.num_displays, ==, 1);
@@ -549,6 +560,11 @@ DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_PITCH) {
 tag->request.value.pitch = DUMMY_VALUE;
 }
 
+/**/
+DECLARE_TEST_CASE(VCHIQ_INIT) {
+g_assert_cmpint(tag->response.value.zero, ==, 0);
+}
+
 
/**/
 int main(int argc, char **argv)
 {
@@ -572,6 +588,7 @@ int main(int argc, char **argv)
 QTEST_ADD_TEST_CASE(GET_CLOCK_RATE, ANY);
 QTEST_ADD_TEST_CASE(GET_MAX_CLOCK_RATE, ANY);
 QTEST_ADD_TEST_CASE(GET_MIN_CLOCK_RATE, ANY);
+QTEST_ADD_TEST_CASE(GET_CLOCKS);
 QTEST_ADD_TEST_CASE(GET_TEMPERATURE);
 QTEST_ADD_TEST_CASE(GET_MAX_TEMPERATURE);
 QTEST_ADD_TEST_CASE(FRAMEBUFFER_ALLOCATE);
@@ -607,6 +624,8 @@ int main(int argc, char **argv)
 QTEST_ADD_TEST_CASE(GET_COMMAND_LINE);
 QTEST_ADD_TEST_CASE(FRAMEBUFFER_GET_NUM_DISPLAYS);
 QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_PITCH);
+QTEST_ADD_TEST_CASE(GET_THROTTLED);
+QTEST_ADD_TEST_CASE(VCHIQ_INIT);
 
 return g_test_run();
 }
-- 
2.34.1




[PATCH v6 02/41] Split out common part of peripherals

2024-02-25 Thread Sergey Kambalin
Pre-setup for BCM2838 introduction

Signed-off-by: Sergey Kambalin 
Reviewed-by: Peter Maydell 
---
 hw/arm/bcm2835_peripherals.c | 198 +++
 hw/arm/bcm2836.c |  24 ++--
 include/hw/arm/bcm2835_peripherals.h |  29 +++-
 include/hw/arm/bcm2836.h |   3 +-
 4 files changed, 154 insertions(+), 100 deletions(-)

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index d5573fd954..ed38a08a57 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -30,9 +30,9 @@
 #define SEPARATE_DMA_IRQ_MAX 10
 #define ORGATED_DMA_IRQ_COUNT 4
 
-static void create_unimp(BCM2835PeripheralState *ps,
- UnimplementedDeviceState *uds,
- const char *name, hwaddr ofs, hwaddr size)
+void create_unimp(BCMSocPeripheralBaseState *ps,
+  UnimplementedDeviceState *uds,
+  const char *name, hwaddr ofs, hwaddr size)
 {
 object_initialize_child(OBJECT(ps), name, uds, TYPE_UNIMPLEMENTED_DEVICE);
 qdev_prop_set_string(DEVICE(uds), "name", name);
@@ -45,9 +45,36 @@ static void create_unimp(BCM2835PeripheralState *ps,
 static void bcm2835_peripherals_init(Object *obj)
 {
 BCM2835PeripheralState *s = BCM2835_PERIPHERALS(obj);
+BCMSocPeripheralBaseState *s_base = BCM_SOC_PERIPHERALS_BASE(obj);
+
+/* Random Number Generator */
+object_initialize_child(obj, "rng", >rng, TYPE_BCM2835_RNG);
+
+/* Thermal */
+object_initialize_child(obj, "thermal", >thermal, TYPE_BCM2835_THERMAL);
+
+/* GPIO */
+object_initialize_child(obj, "gpio", >gpio, TYPE_BCM2835_GPIO);
+
+object_property_add_const_link(OBJECT(>gpio), "sdbus-sdhci",
+   OBJECT(_base->sdhci.sdbus));
+object_property_add_const_link(OBJECT(>gpio), "sdbus-sdhost",
+   OBJECT(_base->sdhost.sdbus));
+
+/* Gated DMA interrupts */
+object_initialize_child(obj, "orgated-dma-irq",
+_base->orgated_dma_irq, TYPE_OR_IRQ);
+object_property_set_int(OBJECT(_base->orgated_dma_irq), "num-lines",
+ORGATED_DMA_IRQ_COUNT, _abort);
+}
+
+static void raspi_peripherals_base_init(Object *obj)
+{
+BCMSocPeripheralBaseState *s = BCM_SOC_PERIPHERALS_BASE(obj);
+BCMSocPeripheralBaseClass *bc = BCM_SOC_PERIPHERALS_BASE_GET_CLASS(obj);
 
 /* Memory region for peripheral devices, which we export to our parent */
-memory_region_init(>peri_mr, obj,"bcm2835-peripherals", 0x100);
+memory_region_init(>peri_mr, obj, "bcm2835-peripherals", bc->peri_size);
 sysbus_init_mmio(SYS_BUS_DEVICE(s), >peri_mr);
 
 /* Internal memory region for peripheral bus addresses (not exported) */
@@ -98,9 +125,6 @@ static void bcm2835_peripherals_init(Object *obj)
 object_property_add_const_link(OBJECT(>property), "dma-mr",
OBJECT(>gpu_bus_mr));
 
-/* Random Number Generator */
-object_initialize_child(obj, "rng", >rng, TYPE_BCM2835_RNG);
-
 /* Extended Mass Media Controller */
 object_initialize_child(obj, "sdhci", >sdhci, TYPE_SYSBUS_SDHCI);
 
@@ -110,25 +134,9 @@ static void bcm2835_peripherals_init(Object *obj)
 /* DMA Channels */
 object_initialize_child(obj, "dma", >dma, TYPE_BCM2835_DMA);
 
-object_initialize_child(obj, "orgated-dma-irq",
->orgated_dma_irq, TYPE_OR_IRQ);
-object_property_set_int(OBJECT(>orgated_dma_irq), "num-lines",
-ORGATED_DMA_IRQ_COUNT, _abort);
-
 object_property_add_const_link(OBJECT(>dma), "dma-mr",
OBJECT(>gpu_bus_mr));
 
-/* Thermal */
-object_initialize_child(obj, "thermal", >thermal, TYPE_BCM2835_THERMAL);
-
-/* GPIO */
-object_initialize_child(obj, "gpio", >gpio, TYPE_BCM2835_GPIO);
-
-object_property_add_const_link(OBJECT(>gpio), "sdbus-sdhci",
-   OBJECT(>sdhci.sdbus));
-object_property_add_const_link(OBJECT(>gpio), "sdbus-sdhost",
-   OBJECT(>sdhost.sdbus));
-
 /* Mphi */
 object_initialize_child(obj, "mphi", >mphi, TYPE_BCM2835_MPHI);
 
@@ -152,7 +160,72 @@ static void bcm2835_peripherals_init(Object *obj)
 
 static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
 {
+MemoryRegion *mphi_mr;
 BCM2835PeripheralState *s = BCM2835_PERIPHERALS(dev);
+BCMSocPeripheralBaseState *s_base = BCM_SOC_PERIPHERALS_BASE(dev);
+int n;
+
+bcm_soc_peripherals_common_realize(dev, errp);
+
+/* Extended Mass Media Controller */
+sysbus_connect_irq(SYS_BUS_DEVICE(_base->sdhci), 0,
+qdev_get_gpio_in_named(DEVICE(_base->ic), BCM2835_IC_GPU_IRQ,
+   INTERRUPT_ARASANSDIO));
+
+ /* Connect DMA 0-12 to the interrupt controller */
+for (n = 0; n <= SEPARATE_DMA_IRQ_MAX; n++) {
+

[PATCH v6 16/41] Add RPi4 RNG200

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 hw/arm/bcm2838.c |   4 +
 hw/arm/bcm2838_peripherals.c |  17 ++
 hw/arm/raspi4b.c |   1 -
 hw/misc/bcm2838_rng200.c | 405 +++
 hw/misc/meson.build  |   1 +
 hw/misc/trace-events |   9 +
 include/hw/arm/bcm2838_peripherals.h |   2 +
 include/hw/misc/bcm2838_rng200.h |  43 +++
 8 files changed, 481 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/bcm2838_rng200.c
 create mode 100644 include/hw/misc/bcm2838_rng200.h

diff --git a/hw/arm/bcm2838.c b/hw/arm/bcm2838.c
index 481b262b02..c330322bd5 100644
--- a/hw/arm/bcm2838.c
+++ b/hw/arm/bcm2838.c
@@ -205,6 +205,10 @@ static void bcm2838_realize(DeviceState *dev, Error **errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(_base->dwc2), 0,
qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_DWC2));
 
+/* Connect RNG200 to the interrupt controller */
+sysbus_connect_irq(SYS_BUS_DEVICE(>rng200), 0,
+   qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_RNG200));
+
 /* Connect DMA 0-6 to the interrupt controller */
 for (int n = GIC_SPI_INTERRUPT_DMA_0; n <= GIC_SPI_INTERRUPT_DMA_6; n++) {
 sysbus_connect_irq(SYS_BUS_DEVICE(_base->dma),
diff --git a/hw/arm/bcm2838_peripherals.c b/hw/arm/bcm2838_peripherals.c
index 23e1154466..4a9cbe6cf6 100644
--- a/hw/arm/bcm2838_peripherals.c
+++ b/hw/arm/bcm2838_peripherals.c
@@ -34,6 +34,9 @@ static void bcm2838_peripherals_init(Object *obj)
bc->peri_low_size);
 sysbus_init_mmio(SYS_BUS_DEVICE(s), >peri_low_mr);
 
+/* Random Number Generator */
+object_initialize_child(obj, "rng200", >rng200, TYPE_BCM2838_RNG200);
+
 /* PCIe Host Bridge */
 object_initialize_child(obj, "pcie-host", >pcie_host,
 TYPE_BCM2838_PCIE_HOST);
@@ -75,6 +78,8 @@ static void bcm2838_peripherals_realize(DeviceState *dev, 
Error **errp)
 BCMSocPeripheralBaseState *s_base = BCM_SOC_PERIPHERALS_BASE(dev);
 MemoryRegion *regs_mr;
 MemoryRegion *mmio_mr;
+MemoryRegion *rng200_mr;
+qemu_irq rng_200_irq;
 
 int n;
 
@@ -88,6 +93,18 @@ static void bcm2838_peripherals_realize(DeviceState *dev, 
Error **errp)
 BCM2838_VC_PERI_LOW_BASE,
 >peri_low_mr_alias, 1);
 
+/* Random Number Generator */
+if (!sysbus_realize(SYS_BUS_DEVICE(>rng200), errp)) {
+return;
+}
+
+rng200_mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(>rng200), 0);
+memory_region_add_subregion(_base->peri_mr, RNG_OFFSET, rng200_mr);
+
+rng_200_irq = qdev_get_gpio_in_named(DEVICE(_base->ic),
+ BCM2835_IC_GPU_IRQ, INTERRUPT_RNG);
+sysbus_connect_irq(SYS_BUS_DEVICE(>rng200), 0, rng_200_irq);
+
 /* Extended Mass Media Controller 2 */
 object_property_set_uint(OBJECT(>emmc2), "sd-spec-version", 3,
  _abort);
diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c
index 2431b0b8c3..3c71fa9a9a 100644
--- a/hw/arm/raspi4b.c
+++ b/hw/arm/raspi4b.c
@@ -67,7 +67,6 @@ static void raspi4_modify_dtb(const struct arm_boot_info 
*info, void *fdt)
 
 /* Temporarily disable following devices until they are implemented */
 const char *nodes_to_remove[] = {
-"brcm,bcm2711-rng200",
 "brcm,bcm2711-thermal",
 "brcm,bcm2711-genet-v5",
 };
diff --git a/hw/misc/bcm2838_rng200.c b/hw/misc/bcm2838_rng200.c
new file mode 100644
index 00..84ed723a1c
--- /dev/null
+++ b/hw/misc/bcm2838_rng200.c
@@ -0,0 +1,405 @@
+/*
+ * BCM2838 Random Number Generator emulation
+ *
+ * Copyright (C) 2022 Sergey Pushkarev 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qom/object_interfaces.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "hw/misc/bcm2838_rng200.h"
+#include "hw/registerfields.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+/* RNG200 registers */
+REG32(RNG_CTRL,   0x00)
+FIELD(RNG_CTRL, RBG_ENABLE,   0 , 1)
+FIELD(RNG_CTRL, RSVD, 1 , 12)
+FIELD(RNG_CTRL, DIV, 13 , 8)
+
+REG32(RNG_SOFT_RESET,0x04)
+REG32(RBG_SOFT_RESET,0x08)
+REG32(RNG_TOTAL_BIT_COUNT,   0x0C)
+REG32(RNG_TOTAL_BIT_COUNT_THRESHOLD, 0x10)
+
+REG32(RNG_INT_STATUS,   0x18)
+FIELD(RNG_INT_STATUS, TOTAL_BITS_COUNT_IRQ, 0, 1)
+FIELD(RNG_INT_STATUS, RSVD0,1, 4)
+FIELD(RNG_INT_STATUS, NIST_FAIL_IRQ,5, 1)
+FIELD(RNG_INT_STATUS, RSVD1,6, 11)
+FIELD(RNG_INT_STATUS, STARTUP_TRANSITIONS_MET_IRQ,  17, 1)
+FIELD(RNG_INT_STATUS, RSVD2,18, 13)
+

[PATCH v6 41/41] Add RPi4B to raspi.rst

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
Reviewed-by: Peter Maydell 
---
 docs/system/arm/raspi.rst | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/docs/system/arm/raspi.rst b/docs/system/arm/raspi.rst
index d0a6f08b2b..c21b27744e 100644
--- a/docs/system/arm/raspi.rst
+++ b/docs/system/arm/raspi.rst
@@ -1,5 +1,5 @@
-Raspberry Pi boards (``raspi0``, ``raspi1ap``, ``raspi2b``, ``raspi3ap``, 
``raspi3b``)
-==
+Raspberry Pi boards (``raspi0``, ``raspi1ap``, ``raspi2b``, ``raspi3ap``, 
``raspi3b``, ``raspi4b-2g``)
+==
 
 
 QEMU provides models of the following Raspberry Pi boards:
@@ -12,12 +12,13 @@ QEMU provides models of the following Raspberry Pi boards:
   Cortex-A53 (4 cores), 512 MiB of RAM
 ``raspi3b``
   Cortex-A53 (4 cores), 1 GiB of RAM
-
+``raspi4b-2g``
+  Cortex-A72 (4 cores), 2 GiB of RAM
 
 Implemented devices
 ---
 
- * ARM1176JZF-S, Cortex-A7 or Cortex-A53 CPU
+ * ARM1176JZF-S, Cortex-A7, Cortex-A53 or Cortex-A72 CPU
  * Interrupt controller
  * DMA controller
  * Clock and reset controller (CPRMAN)
@@ -34,6 +35,8 @@ Implemented devices
  * MailBox controller (MBOX)
  * VideoCore firmware (property)
  * Peripheral SPI controller (SPI)
+ * PCIE Root Port (raspi4b-2g)
+ * GENET Ethernet Controller (raspi4b-2g)
 
 
 Missing devices
-- 
2.34.1




[PATCH v6 30/41] Add Rpi4b boot tests

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 tests/avocado/boot_linux_console.py | 92 +
 1 file changed, 92 insertions(+)

diff --git a/tests/avocado/boot_linux_console.py 
b/tests/avocado/boot_linux_console.py
index a00202df3c..f5ec6de0f1 100644
--- a/tests/avocado/boot_linux_console.py
+++ b/tests/avocado/boot_linux_console.py
@@ -501,6 +501,98 @@ def test_arm_raspi2_initrd(self):
 # Wait for VM to shut down gracefully
 self.vm.wait()
 
+def test_arm_raspi4(self):
+"""
+:avocado: tags=arch:aarch64
+:avocado: tags=machine:raspi4b-2g
+:avocado: tags=device:pl011
+:avocado: tags=accel:tcg
+:avocado: tags=rpi4b
+
+The kernel can be rebuilt using the kernel source referenced
+and following the instructions on the on:
+https://www.raspberrypi.org/documentation/linux/kernel/building.md
+"""
+
+deb_url = ('http://archive.raspberrypi.org/debian/'
+'pool/main/r/raspberrypi-firmware/'
+'raspberrypi-kernel_1.20230106-1_arm64.deb')
+deb_hash = '08dc55696535b18a6d4fe6fa10d4c0d905cbb2ed'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+kernel_path = self.extract_from_deb(deb_path, '/boot/kernel8.img')
+dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2711-rpi-4-b.dtb')
+
+self.vm.set_console()
+kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+   'earlycon=pl011,mmio32,0xfe201000 ' +
+   'console=ttyAMA0,115200 ' +
+   'root=/dev/mmcblk1p2 rootwait ' +
+   'dwc_otg.fiq_fsm_enable=0')
+self.vm.add_args('-kernel', kernel_path,
+ '-dtb', dtb_path,
+ '-append', kernel_command_line,
+ '-device', 'qemu-xhci,bus=pcie.1,id=xhci',
+ '-device', 'usb-kbd,bus=xhci.0')
+self.vm.launch()
+console_pattern = 'Kernel command line: %s' % kernel_command_line
+self.wait_for_console_pattern(console_pattern)
+console_pattern = 'Product: QEMU USB Keyboard'
+self.wait_for_console_pattern(console_pattern)
+
+
+def test_arm_raspi4_initrd(self):
+"""
+:avocado: tags=arch:aarch64
+:avocado: tags=machine:raspi4b-2g
+:avocado: tags=device:pl011
+:avocado: tags=accel:tcg
+:avocado: tags=rpi4b
+
+The kernel can be rebuilt using the kernel source referenced
+and following the instructions on the on:
+https://www.raspberrypi.org/documentation/linux/kernel/building.md
+"""
+deb_url = ('http://archive.raspberrypi.org/debian/'
+'pool/main/r/raspberrypi-firmware/'
+'raspberrypi-kernel_1.20230106-1_arm64.deb')
+deb_hash = '08dc55696535b18a6d4fe6fa10d4c0d905cbb2ed'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+kernel_path = self.extract_from_deb(deb_path, '/boot/kernel8.img')
+dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2711-rpi-4-b.dtb')
+
+initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
+  '86b2be1384d41c8c388e63078a847f1e1c4cb1de/rootfs/'
+  'arm64/rootfs.cpio.gz')
+initrd_hash = 'f3d4f9fa92a49aa542f1b44d34be77bbf8ca5b9d'
+initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
+initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
+archive.gzip_uncompress(initrd_path_gz, initrd_path)
+
+self.vm.set_console()
+kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+   'earlycon=pl011,mmio32,0xfe201000 ' +
+   'console=ttyAMA0,115200 ' +
+   'panic=-1 noreboot ' +
+   'dwc_otg.fiq_fsm_enable=0')
+self.vm.add_args('-kernel', kernel_path,
+ '-dtb', dtb_path,
+ '-initrd', initrd_path,
+ '-append', kernel_command_line,
+ '-device', 'qemu-xhci,bus=pcie.1,id=xhci',
+ '-device', 'usb-kbd,bus=xhci.0',
+ '-no-reboot')
+self.vm.launch()
+self.wait_for_console_pattern('Boot successful.')
+
+exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
+'BCM2835')
+exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
+'cprman@7e101000')
+exec_command_and_wait_for_pattern(self, 'halt', 'reboot: System 
halted')
+# TODO: Raspberry Pi4 doesn't shut down properly with recent kernels
+# Wait for VM to shut down gracefully
+#self.vm.wait()
+
 def test_arm_exynos4210_initrd(self):

[PATCH v6 29/41] Enable BCM2838 GENET controller

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 hw/arm/bcm2838.c |  6 ++
 hw/arm/bcm2838_peripherals.c | 11 +++
 hw/arm/raspi4b.c | 20 +---
 include/hw/arm/bcm2838_peripherals.h |  2 ++
 4 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/hw/arm/bcm2838.c b/hw/arm/bcm2838.c
index c330322bd5..a873162f09 100644
--- a/hw/arm/bcm2838.c
+++ b/hw/arm/bcm2838.c
@@ -239,6 +239,12 @@ static void bcm2838_realize(DeviceState *dev, Error **errp)
   int_n);
 }
 
+/* Connect Gigabit Ethernet controller to the interrupt controller */
+sysbus_connect_irq(SYS_BUS_DEVICE(>genet), 0,
+   qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_GENET_A));
+sysbus_connect_irq(SYS_BUS_DEVICE(>genet), 1,
+   qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_GENET_B));
+
 /* Pass through inbound GPIO lines to the GIC */
 qdev_init_gpio_in(dev, bcm2838_gic_set_irq, GIC_NUM_IRQS);
 
diff --git a/hw/arm/bcm2838_peripherals.c b/hw/arm/bcm2838_peripherals.c
index 1f41028649..c6083e36de 100644
--- a/hw/arm/bcm2838_peripherals.c
+++ b/hw/arm/bcm2838_peripherals.c
@@ -47,6 +47,10 @@ static void bcm2838_peripherals_init(Object *obj)
 object_initialize_child(obj, "pcie-host", >pcie_host,
 TYPE_BCM2838_PCIE_HOST);
 
+/* Gigabit Ethernet */
+object_initialize_child(obj, "genet", >genet, TYPE_BCM2838_GENET);
+qemu_configure_nic_device(DEVICE(>genet), true, NULL);
+
 /* Extended Mass Media Controller 2 */
 object_initialize_child(obj, "emmc2", >emmc2, TYPE_SYSBUS_SDHCI);
 
@@ -231,6 +235,13 @@ static void bcm2838_peripherals_realize(DeviceState *dev, 
Error **errp)
 memory_region_add_subregion(get_system_memory(), PCIE_MMIO_ARM_OFFSET,
 mmio_mr);
 
+/* Gigabit Ethernet */
+if (!sysbus_realize(SYS_BUS_DEVICE(>genet), errp)) {
+return;
+}
+regs_mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(>genet), 0);
+memory_region_add_subregion(>peri_low_mr, GENET_OFFSET, regs_mr);
+
 create_unimp(s_base, >clkisp, "bcm2835-clkisp", CLOCK_ISP_OFFSET,
  CLOCK_ISP_SIZE);
 
diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c
index 175fd2c4fa..d498bc6215 100644
--- a/hw/arm/raspi4b.c
+++ b/hw/arm/raspi4b.c
@@ -63,25 +63,7 @@ static int raspi_add_memory_node(void *fdt, hwaddr mem_base, 
hwaddr mem_len)
 
 static void raspi4_modify_dtb(const struct arm_boot_info *info, void *fdt)
 {
-uint64_t ram_size;
-
-/* Temporarily disable following devices until they are implemented */
-const char *nodes_to_remove[] = {
-"brcm,bcm2711-genet-v5",
-};
-
-for (int i = 0; i < ARRAY_SIZE(nodes_to_remove); i++) {
-const char *dev_str = nodes_to_remove[i];
-
-int offset = fdt_node_offset_by_compatible(fdt, -1, dev_str);
-if (offset >= 0) {
-if (!fdt_nop_node(fdt, offset)) {
-warn_report("bcm2711 dtc: %s has been disabled!", dev_str);
-}
-}
-}
-
-ram_size = board_ram_size(info->board_id);
+uint64_t ram_size = board_ram_size(info->board_id);
 
 if (info->ram_size > UPPER_RAM_BASE) {
 raspi_add_memory_node(fdt, UPPER_RAM_BASE, ram_size - UPPER_RAM_BASE);
diff --git a/include/hw/arm/bcm2838_peripherals.h 
b/include/hw/arm/bcm2838_peripherals.h
index 555d3a393f..5588b99098 100644
--- a/include/hw/arm/bcm2838_peripherals.h
+++ b/include/hw/arm/bcm2838_peripherals.h
@@ -13,6 +13,7 @@
 #include "hw/misc/bcm2838_rng200.h"
 #include "hw/misc/bcm2838_thermal.h"
 #include "hw/arm/bcm2838_pcie.h"
+#include "hw/net/bcm2838_genet.h"
 #include "hw/sd/sdhci.h"
 #include "hw/gpio/bcm2838_gpio.h"
 
@@ -73,6 +74,7 @@ struct BCM2838PeripheralState {
 SDHCIState emmc2;
 BCM2838PcieHostState pcie_host;
 BCM2838GpioState gpio;
+BCM2838GenetState genet;
 
 OrIRQState mmc_irq_orgate;
 OrIRQState dma_7_8_irq_orgate;
-- 
2.34.1




[PATCH v6 13/41] Add BCM2838 PCIE Root Complex

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 hw/arm/bcm2838_pcie.c | 82 +++
 hw/arm/meson.build|  5 ++-
 include/hw/arm/bcm2838_pcie.h | 53 ++
 3 files changed, 139 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/bcm2838_pcie.c
 create mode 100644 include/hw/arm/bcm2838_pcie.h

diff --git a/hw/arm/bcm2838_pcie.c b/hw/arm/bcm2838_pcie.c
new file mode 100644
index 00..cb1370433e
--- /dev/null
+++ b/hw/arm/bcm2838_pcie.c
@@ -0,0 +1,82 @@
+/*
+ * BCM2838 PCIe Root Complex emulation
+ *
+ * Copyright (C) 2022 Ovchinnikov Vitalii 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/irq.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "qemu/module.h"
+#include "hw/arm/bcm2838_pcie.h"
+#include "trace.h"
+
+/*
+ * RC root part (D0:F0)
+ */
+
+static void bcm2838_pcie_root_port_reset_hold(Object *obj)
+{
+PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(obj);
+PCIDevice *dev = PCI_DEVICE(obj);
+BCM2838PcieRootState *s = BCM2838_PCIE_ROOT(dev);
+
+if (rpc->parent_phases.hold) {
+rpc->parent_phases.hold(obj);
+}
+
+memset(s->regs, 0xFF, sizeof(s->regs));
+}
+
+static void bcm2838_pcie_root_init(Object *obj)
+{
+PCIBridge *br = PCI_BRIDGE(obj);
+br->bus_name = "pcie.1";
+}
+
+static void bcm2838_pcie_root_class_init(ObjectClass *class, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(class);
+PCIDeviceClass *k = PCI_DEVICE_CLASS(class);
+ResettableClass *rc = RESETTABLE_CLASS(class);
+PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(class);
+
+dc->desc = "BCM2711 PCIe Bridge";
+/*
+ * PCI-facing part of the host bridge, not usable without the host-facing
+ * part, which can't be device_add'ed.
+ */
+
+resettable_class_set_parent_phases(rc, NULL,
+   bcm2838_pcie_root_port_reset_hold,
+   NULL, >parent_phases);
+
+dc->user_creatable = false;
+k->vendor_id = BCM2838_PCIE_VENDOR_ID;
+k->device_id = BCM2838_PCIE_DEVICE_ID;
+k->revision = BCM2838_PCIE_REVISION;
+
+rpc->exp_offset = BCM2838_PCIE_EXP_CAP_OFFSET;
+rpc->aer_offset = BCM2838_PCIE_AER_CAP_OFFSET;
+}
+
+static const TypeInfo bcm2838_pcie_root_info = {
+.name = TYPE_BCM2838_PCIE_ROOT,
+.parent = TYPE_PCIE_ROOT_PORT,
+.instance_size = sizeof(BCM2838PcieRootState),
+.instance_init = bcm2838_pcie_root_init,
+.class_init = bcm2838_pcie_root_class_init,
+};
+
+static void bcm2838_pcie_register(void)
+{
+type_register_static(_pcie_root_info);
+}
+
+type_init(bcm2838_pcie_register)
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 6808135c1f..39f6df7431 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -30,7 +30,10 @@ arm_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: 
files('allwinner-a10.c', 'cubi
 arm_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3.c', 
'orangepi.c'))
 arm_ss.add(when: 'CONFIG_ALLWINNER_R40', if_true: files('allwinner-r40.c', 
'bananapi_m2u.c'))
 arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c'))
-arm_ss.add(when: ['CONFIG_RASPI', 'TARGET_AARCH64'], if_true: 
files('bcm2838.c', 'raspi4b.c'))
+arm_ss.add(when: ['CONFIG_RASPI', 'TARGET_AARCH64'], if_true: files(
+  'bcm2838.c',
+  'bcm2838_pcie.c',
+  'raspi4b.c'))
 arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
 arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
 arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
diff --git a/include/hw/arm/bcm2838_pcie.h b/include/hw/arm/bcm2838_pcie.h
new file mode 100644
index 00..39828f817f
--- /dev/null
+++ b/include/hw/arm/bcm2838_pcie.h
@@ -0,0 +1,53 @@
+/*
+ * BCM2838 PCIe Root Complex emulation
+ *
+ * Copyright (C) 2022 Ovchinnikov Vitalii 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef BCM2838_PCIE_H
+#define BCM2838_PCIE_H
+
+#include "exec/hwaddr.h"
+#include "hw/sysbus.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pcie_host.h"
+#include "hw/pci/pcie_port.h"
+#include "qom/object.h"
+
+#define TYPE_BCM2838_PCIE_ROOT "bcm2838-pcie-root"
+OBJECT_DECLARE_TYPE(BCM2838PcieRootState, BCM2838PcieRootClass,
+BCM2838_PCIE_ROOT)
+
+#define BCM2838_PCIE_VENDOR_ID  0x14E4
+#define BCM2838_PCIE_DEVICE_ID  0x2711
+#define BCM2838_PCIE_REVISION   20
+
+#define BCM2838_PCIE_REGS_SIZE  0x9310
+#define BCM2838_PCIE_NUM_IRQS   4
+
+#define BCM2838_PCIE_EXP_CAP_OFFSET 0xAC
+#define BCM2838_PCIE_AER_CAP_OFFSET 0x100
+
+#define BCM2838_PCIE_EXT_CFG_DATA   0x8000
+#define BCM2838_PCIE_EXT_CFG_INDEX  0x9000
+
+struct BCM2838PcieRootState {
+/*< private >*/
+PCIESlot parent_obj;
+
+/*< public >*/
+uint8_t regs[BCM2838_PCIE_REGS_SIZE - 

[PATCH v6 26/41] Implement GENET MDIO

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 hw/net/bcm2838_genet.c | 126 -
 include/hw/net/bcm2838_genet.h |   3 +-
 2 files changed, 126 insertions(+), 3 deletions(-)

diff --git a/hw/net/bcm2838_genet.c b/hw/net/bcm2838_genet.c
index 56ff6a6f39..1fae3ecbc2 100644
--- a/hw/net/bcm2838_genet.c
+++ b/hw/net/bcm2838_genet.c
@@ -213,6 +213,7 @@ FIELD(GENET_PHY_STAT_1000, LOCALRXOK, 13, 1)
 FIELD(GENET_PHY_STAT_1000, MSRES, 14, 1)
 FIELD(GENET_PHY_STAT_1000, MSFAIL,15, 1)
 
+/* There are two data representations for PHY_AUX_CTRL register */
 REG16(GENET_PHY_AUX_CTRL_0,  0)
 FIELD(GENET_PHY_AUX_CTRL_0, REG_ID_MASK, 0, 3)
 FIELD(GENET_PHY_AUX_CTRL_0, RSVD_3,  3, 1)
@@ -269,6 +270,123 @@ static void bcm2838_genet_set_irq_prio(BCM2838GenetState 
*s)
 qemu_set_irq(s->irq_prio, level);
 }
 
+static void bcm2838_genet_phy_aux_ctl_write(BCM2838GenetState *s,
+uint16_t value)
+{
+uint16_t reg_id = FIELD_EX16(value, GENET_PHY_AUX_CTRL_0, REG_ID);
+uint16_t reg_id_mask = FIELD_EX16(value, GENET_PHY_AUX_CTRL_0, 
REG_ID_MASK);
+uint16_t misc_wren = FIELD_EX16(value, GENET_PHY_AUX_CTRL_0, MISC_WREN);
+uint16_t reg_data = FIELD_EX16(value, GENET_PHY_AUX_CTRL_0, REG_DATA);
+uint16_t reg_data12 = FIELD_EX16(value, GENET_PHY_AUX_CTRL_1, REG_DATA);
+
+uint16_t *phy_aux_ctl_shd_reg_id = (uint16_t *)>phy_aux_ctl_shd_regs + 
reg_id;
+uint16_t *phy_aux_ctl_shd_reg_id_mask = (uint16_t 
*)>phy_aux_ctl_shd_regs + reg_id_mask;
+
+if (reg_id_mask == BCM2838_GENET_PHY_AUX_CTL_MISC) {
+if (reg_id == BCM2838_GENET_PHY_AUX_CTL_MISC) {
+if (misc_wren == 0) {
+/* write for subsequent read (8-bit from AUX_CTL_MISC) */
+FIELD_DP16(value, GENET_PHY_AUX_CTRL_0, REG_DATA, 
*phy_aux_ctl_shd_reg_id);
+} else {
+/* write 8 bits to AUX_CTL_MISC */
+*phy_aux_ctl_shd_reg_id_mask = reg_data;
+}
+} else {
+/* write for subsequent read (12-bit) */
+FIELD_DP16(value, GENET_PHY_AUX_CTRL_1, REG_DATA, 
*phy_aux_ctl_shd_reg_id);
+}
+} else {
+/* write 12 bits */
+*phy_aux_ctl_shd_reg_id_mask = reg_data12;
+}
+
+s->phy_regs.aux_ctl = value;
+}
+
+static void bcm2838_genet_phy_shadow_write(BCM2838GenetState *s,
+   uint16_t value)
+{
+uint16_t reg_id = FIELD_EX16(value, GENET_PHY_SHADOW, REG_ID);
+uint16_t wr = FIELD_EX16(value, GENET_PHY_SHADOW, WR);
+uint16_t reg_data = FIELD_EX16(value, GENET_PHY_SHADOW, REG_DATA);
+
+uint16_t *phy_shd_reg = (uint16_t *)>phy_shd_regs + reg_id;
+
+if (wr == 0) {
+FIELD_DP16(value, GENET_PHY_SHADOW, REG_DATA, *phy_shd_reg);
+} else {
+*phy_shd_reg = reg_data;
+}
+
+s->phy_regs.shd = value;
+}
+
+static void bcm2838_genet_phy_exp_shadow_write(BCM2838GenetState *s,
+   uint16_t value)
+{
+/* TODO Stub implementation without side effect,
+just storing registers values */
+uint16_t reg_id = FIELD_EX16(s->phy_regs.exp_ctrl,
+ GENET_PHY_EXP_SEL, REG_ID);
+uint16_t block_id = FIELD_EX16(s->phy_regs.exp_ctrl,
+   GENET_PHY_EXP_SEL, BLOCK_ID);
+
+s->phy_exp_shd_regs.regs[block_id][reg_id] = value;
+}
+
+static uint16_t bcm2838_genet_phy_exp_shadow_read(BCM2838GenetState *s)
+{
+uint16_t reg_id = FIELD_EX16(s->phy_regs.exp_ctrl,
+ GENET_PHY_EXP_SEL, REG_ID);
+uint16_t block_id = FIELD_EX16(s->phy_regs.exp_ctrl,
+   GENET_PHY_EXP_SEL, BLOCK_ID);
+
+return s->phy_exp_shd_regs.regs[block_id][reg_id];
+}
+
+static uint64_t bcm2838_genet_mdio_cmd(BCM2838GenetState *s, uint64_t cmd)
+{
+uint32_t phy_reg_id = FIELD_EX32(cmd, GENET_UMAC_MDIO_CMD, REG_ID);
+uint32_t phy_reg_data = FIELD_EX32(cmd, GENET_UMAC_MDIO_CMD, REG_DATA);
+uint32_t start_busy = FIELD_EX32(cmd, GENET_UMAC_MDIO_CMD, START_BUSY);
+uint32_t rd = FIELD_EX32(cmd, GENET_UMAC_MDIO_CMD, RD);
+uint32_t wr = FIELD_EX32(cmd, GENET_UMAC_MDIO_CMD, WR);
+uint16_t *phy_reg = (uint16_t *)>phy_regs + phy_reg_id;
+
+uint16_t anrestart = FIELD_EX16(phy_reg_data, GENET_PHY_BMCR, ANRESTART);
+
+if (start_busy != 0) {
+cmd = FIELD_DP32(cmd, GENET_UMAC_MDIO_CMD, START_BUSY, 0);
+
+if (rd != 0) {
+if (phy_reg_id == BCM2838_GENET_EXP_DATA) {
+cmd = FIELD_DP32(cmd, GENET_UMAC_MDIO_CMD, REG_DATA,
+ bcm2838_genet_phy_exp_shadow_read(s));
+} else {
+cmd = FIELD_DP32(cmd, GENET_UMAC_MDIO_CMD, REG_DATA, *phy_reg);
+}
+} else if (wr != 0) {
+if (phy_reg_id == BCM2838_GENET_PHY_AUX_CTL) {
+bcm2838_genet_phy_aux_ctl_write(s, 

[PATCH v6 36/41] Add mailbox property tests. Part 1

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 tests/qtest/bcm2838-mailbox.c|   1 -
 tests/qtest/bcm2838-mbox-property-test.c | 207 +++
 tests/qtest/meson.build  |   2 +-
 3 files changed, 208 insertions(+), 2 deletions(-)
 create mode 100644 tests/qtest/bcm2838-mbox-property-test.c

diff --git a/tests/qtest/bcm2838-mailbox.c b/tests/qtest/bcm2838-mailbox.c
index 1efd3c628a..0928a3dff8 100644
--- a/tests/qtest/bcm2838-mailbox.c
+++ b/tests/qtest/bcm2838-mailbox.c
@@ -11,7 +11,6 @@
 #include "hw/registerfields.h"
 #include "libqtest-single.h"
 #include "bcm2838-mailbox.h"
-#include "hw/arm/raspberrypi-fw-defs.h"
 
 REG32(MBOX_EXCHNG_REG,  0)
 FIELD(MBOX_EXCHNG_REG, CHANNEL, 0, 4)
diff --git a/tests/qtest/bcm2838-mbox-property-test.c 
b/tests/qtest/bcm2838-mbox-property-test.c
new file mode 100644
index 00..acb421915b
--- /dev/null
+++ b/tests/qtest/bcm2838-mbox-property-test.c
@@ -0,0 +1,207 @@
+/*
+ * Tests set for BCM2838 mailbox property interface.
+ *
+ * Copyright (c) 2022 Auriga
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/registerfields.h"
+#include "libqtest-single.h"
+#include "bcm2838-mailbox.h"
+#include "hw/arm/raspberrypi-fw-defs.h"
+
+REG32(MBOX_SIZE_STAT,  0)
+FIELD(MBOX_SIZE_STAT, SIZE,0, 31)
+FIELD(MBOX_SIZE_STAT, SUCCESS, 31, 1)
+
+REG32(SET_POWER_STATE_CMD,0)
+FIELD(SET_POWER_STATE_CMD, EN,0, 1)
+FIELD(SET_POWER_STATE_CMD, WAIT,  1, 1)
+
+REG32(GET_CLOCK_STATE_CMD,0)
+FIELD(GET_CLOCK_STATE_CMD, EN,0, 1)
+FIELD(GET_CLOCK_STATE_CMD, NPRES, 1, 1)
+
+#define MBOX_TEST_MESSAGE_ADDRESS 0x1000
+
+#define TEST_TAG(x) RPI_FWREQ_ ## x
+#define TEST_TAG_TYPE(x) TAG_##x##_t
+
+#define TEST_FN_NAME(test, subtest) \
+test ## _ ## subtest ## _test
+
+#define SETUP_FN_NAME(test, subtest) \
+test ## _ ## subtest ## _setup
+
+#define CHECK_FN_NAME(test, subtest) \
+test ## _ ## subtest ## _spec_check
+
+#define DECLARE_TEST_CASE_SETUP(testname, ...)  \
+void SETUP_FN_NAME(testname, __VA_ARGS__)   \
+ (TEST_TAG_TYPE(testname) * tag)
+
+/**/
+#define DECLARE_TEST_CASE(testname, ...)   
\
+__attribute__((weak))  
\
+void SETUP_FN_NAME(testname, __VA_ARGS__)  
\
+  (TEST_TAG_TYPE(testname) * tag); 
\
+static void CHECK_FN_NAME(testname, __VA_ARGS__)   
\
+ (TEST_TAG_TYPE(testname) *tag);   
\
+static void TEST_FN_NAME(testname, __VA_ARGS__)(void) {
\
+struct {   
\
+MboxBufHeader header;  
\
+TEST_TAG_TYPE(testname) tag;   
\
+uint32_t end_tag;  
\
+} mailbox_buffer = { 0 };  
\
+   
\
+QTestState *qts = qtest_init("-machine raspi4b-2g");   
\
+   
\
+mailbox_buffer.header.size = sizeof(mailbox_buffer);   
\
+mailbox_buffer.header.req_resp_code = MBOX_PROCESS_REQUEST;
\
+   
\
+mailbox_buffer.tag.id = TEST_TAG(testname);
\
+mailbox_buffer.tag.value_buffer_size = MAX(
\
+sizeof(mailbox_buffer.tag.request.value),  
\
+sizeof(mailbox_buffer.tag.response.value));
\
+mailbox_buffer.tag.request.zero = 0;   
\
+   
\
+mailbox_buffer.end_tag = RPI_FWREQ_PROPERTY_END;   
\
+   
\
+if (SETUP_FN_NAME(testname, __VA_ARGS__)) {
\
+SETUP_FN_NAME(testname, __VA_ARGS__)(_buffer.tag); 
\
+}  
\
+   
\
+qtest_memwrite(qts, MBOX_TEST_MESSAGE_ADDRESS, 
\
+_buffer, sizeof(mailbox_buffer));  
\
+

[PATCH v6 14/41] Add BCM2838 PCIE host

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 hw/arm/bcm2838_pcie.c | 217 +-
 hw/arm/trace-events   |   4 +
 include/hw/arm/bcm2838_pcie.h |  22 
 3 files changed, 241 insertions(+), 2 deletions(-)

diff --git a/hw/arm/bcm2838_pcie.c b/hw/arm/bcm2838_pcie.c
index cb1370433e..348263d9fb 100644
--- a/hw/arm/bcm2838_pcie.c
+++ b/hw/arm/bcm2838_pcie.c
@@ -12,11 +12,220 @@
 #include "hw/irq.h"
 #include "hw/pci-host/gpex.h"
 #include "hw/qdev-properties.h"
-#include "migration/vmstate.h"
-#include "qemu/module.h"
 #include "hw/arm/bcm2838_pcie.h"
 #include "trace.h"
 
+static uint32_t bcm2838_pcie_config_read(PCIDevice *d,
+ uint32_t address, int len)
+{
+return pci_default_read_config(d, address, len);
+}
+
+static void bcm2838_pcie_config_write(PCIDevice *d, uint32_t addr, uint32_t 
val,
+  int len)
+{
+return pci_default_write_config(d, addr, val, len);
+}
+
+static uint64_t bcm2838_pcie_host_read(void *opaque, hwaddr offset,
+   unsigned size) {
+hwaddr mmcfg_addr;
+uint64_t value = ~0;
+BCM2838PcieHostState *s = opaque;
+PCIExpressHost *pcie_hb = PCIE_HOST_BRIDGE(s);
+uint8_t *root_regs = s->root_port.regs;
+uint32_t *cfg_idx = (uint32_t *)(root_regs + BCM2838_PCIE_EXT_CFG_INDEX
+ - PCIE_CONFIG_SPACE_SIZE);
+
+if (offset - PCIE_CONFIG_SPACE_SIZE + size <= sizeof(s->root_port.regs)) {
+switch (offset) {
+case BCM2838_PCIE_EXT_CFG_DATA
+... BCM2838_PCIE_EXT_CFG_DATA + PCIE_CONFIG_SPACE_SIZE - 1:
+mmcfg_addr = *cfg_idx
+| PCIE_MMCFG_CONFOFFSET(offset - BCM2838_PCIE_EXT_CFG_DATA);
+value = pcie_hb->mmio.ops->read(opaque, mmcfg_addr, size);
+break;
+default:
+memcpy(, root_regs + offset - PCIE_CONFIG_SPACE_SIZE, size);
+}
+} else {
+qemu_log_mask(
+LOG_GUEST_ERROR,
+"%s: out-of-range access, %u bytes @ offset 0x%04" PRIx64 "\n",
+__func__, size, offset);
+}
+
+trace_bcm2838_pcie_host_read(size, offset, value);
+return value;
+}
+
+static void bcm2838_pcie_host_write(void *opaque, hwaddr offset,
+uint64_t value, unsigned size) {
+hwaddr mmcfg_addr;
+BCM2838PcieHostState *s = opaque;
+PCIExpressHost *pcie_hb = PCIE_HOST_BRIDGE(s);
+uint8_t *root_regs = s->root_port.regs;
+uint32_t *cfg_idx = (uint32_t *)(root_regs + BCM2838_PCIE_EXT_CFG_INDEX
+ - PCIE_CONFIG_SPACE_SIZE);
+
+trace_bcm2838_pcie_host_write(size, offset, value);
+
+if (offset - PCIE_CONFIG_SPACE_SIZE + size <= sizeof(s->root_port.regs)) {
+switch (offset) {
+case BCM2838_PCIE_EXT_CFG_DATA
+... BCM2838_PCIE_EXT_CFG_DATA + PCIE_CONFIG_SPACE_SIZE - 1:
+mmcfg_addr = *cfg_idx
+| PCIE_MMCFG_CONFOFFSET(offset - BCM2838_PCIE_EXT_CFG_DATA);
+pcie_hb->mmio.ops->write(opaque, mmcfg_addr, value, size);
+break;
+default:
+memcpy(root_regs + offset - PCIE_CONFIG_SPACE_SIZE, , size);
+}
+} else {
+qemu_log_mask(
+LOG_GUEST_ERROR,
+"%s: out-of-range access, %u bytes @ offset 0x%04" PRIx64 "\n",
+__func__, size, offset);
+}
+}
+
+static const MemoryRegionOps bcm2838_pcie_host_ops = {
+.read = bcm2838_pcie_host_read,
+.write = bcm2838_pcie_host_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {.max_access_size = sizeof(uint64_t)},
+};
+
+int bcm2838_pcie_host_set_irq_num(BCM2838PcieHostState *s, int index, int spi)
+{
+if (index >= BCM2838_PCIE_NUM_IRQS) {
+return -EINVAL;
+}
+
+s->irq_num[index] = spi;
+return 0;
+}
+
+static void bcm2838_pcie_host_set_irq(void *opaque, int irq_num, int level)
+{
+BCM2838PcieHostState *s = opaque;
+
+qemu_set_irq(s->irq[irq_num], level);
+}
+
+static PCIINTxRoute bcm2838_pcie_host_route_intx_pin_to_irq(void *opaque,
+int pin)
+{
+PCIINTxRoute route;
+BCM2838PcieHostState *s = opaque;
+
+route.irq = s->irq_num[pin];
+route.mode = route.irq < 0 ? PCI_INTX_DISABLED : PCI_INTX_ENABLED;
+
+return route;
+}
+
+static int bcm2838_pcie_host_map_irq(PCIDevice *pci_dev, int pin)
+{
+return pin;
+}
+
+static void bcm2838_pcie_host_realize(DeviceState *dev, Error **errp)
+{
+PCIHostState *pci = PCI_HOST_BRIDGE(dev);
+BCM2838PcieHostState *s = BCM2838_PCIE_HOST(dev);
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+int i;
+
+memory_region_init_io(>cfg_regs, OBJECT(s), _pcie_host_ops, s,
+  "bcm2838_pcie_cfg_regs", BCM2838_PCIE_REGS_SIZE);
+sysbus_init_mmio(sbd, >cfg_regs);
+
+/*
+ * The MemoryRegions io_mmio and 

[PATCH v6 34/41] Add mailbox tests tags. Part 2

2024-02-25 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 tests/qtest/bcm2838-mailbox.h | 152 ++
 1 file changed, 152 insertions(+)

diff --git a/tests/qtest/bcm2838-mailbox.h b/tests/qtest/bcm2838-mailbox.h
index 1360fbb8cf..b4f7b7b314 100644
--- a/tests/qtest/bcm2838-mailbox.h
+++ b/tests/qtest/bcm2838-mailbox.h
@@ -294,6 +294,158 @@ 
DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT_t,
 uint32_t height;
 });
 
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_DEPTH_t,
+struct {},
+struct {
+uint32_t bpp;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_TEST_DEPTH_t,
+struct {
+uint32_t bpp;
+},
+struct {
+uint32_t bpp;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_DEPTH_t,
+struct {
+uint32_t bpp;
+},
+struct {
+uint32_t bpp;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_PIXEL_ORDER_t,
+struct {},
+struct {
+uint32_t pixel_order;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_TEST_PIXEL_ORDER_t,
+struct {
+uint32_t pixel_order;
+},
+struct {
+uint32_t pixel_order;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_PIXEL_ORDER_t,
+struct {
+uint32_t pixel_order;
+},
+struct {
+uint32_t pixel_order;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_ALPHA_MODE_t,
+struct {},
+struct {
+uint32_t alpha_mode;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_TEST_ALPHA_MODE_t,
+struct {
+uint32_t alpha_mode;
+},
+struct {
+uint32_t alpha_mode;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_ALPHA_MODE_t,
+struct {
+uint32_t alpha_mode;
+},
+struct {
+uint32_t alpha_mode;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_PITCH_t,
+struct {},
+struct {
+uint32_t pitch;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_PITCH_t,
+struct {
+uint32_t pitch;
+},
+struct {});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_VIRTUAL_OFFSET_t,
+struct {},
+struct {
+uint32_t x;
+uint32_t y;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_TEST_VIRTUAL_OFFSET_t,
+struct {
+uint32_t x;
+uint32_t y;
+},
+struct {
+uint32_t x;
+uint32_t y;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_VIRTUAL_OFFSET_t,
+struct {
+uint32_t x;
+uint32_t y;
+},
+struct {
+uint32_t x;
+uint32_t y;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_OVERSCAN_t,
+struct {},
+struct {
+uint32_t top;
+uint32_t bottom;
+uint32_t left;
+uint32_t right;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_TEST_OVERSCAN_t,
+struct {
+uint32_t top;
+uint32_t bottom;
+uint32_t left;
+uint32_t right;
+},
+struct {
+uint32_t top;
+uint32_t bottom;
+uint32_t left;
+uint32_t right;
+});
+
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_OVERSCAN_t,
+struct {
+uint32_t top;
+uint32_t bottom;
+uint32_t left;
+uint32_t right;
+},
+struct {
+uint32_t top;
+uint32_t bottom;
+uint32_t left;
+uint32_t right;
+});
+
+DECLARE_TAG_TYPE(TAG_GET_COMMAND_LINE_t,
+struct {},
+struct {});
+
+DECLARE_TAG_TYPE(TAG_GET_DMA_CHANNELS_t,
+struct {},
+struct {
+uint32_t mask;
+});
+
 int mbox0_has_data(void);
 void mbox0_read_message(uint8_t channel, void *msgbuf, size_t msgbuf_size);
 void mbox1_write_message(uint8_t channel, uint32_t msg_addr);
-- 
2.34.1




  1   2   >