Re: [PATCH 09/12] target-info: register le and be TargetInfo variants
Pierrick Bouvier <[email protected]>
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-arm,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
On 8/23/2026 8:07 AM, Yonggang Luo wrote: > - Register target-info-<name>-le and -be from one system > target-info-def.c unit, sharing arch fields. > - Mark is_default from TARGET_BIG_ENDIAN so riscv/arm stay LE and > ppc/s390x stay BE when -target is omitted. > - Pick the unique default in target_info_qom_set_target() when more > than one TargetInfo is registered. Leave user-mode as a single > target_info(). > > Signed-off-by: Yonggang Luo <[email protected]> > --- > include/qemu/target-info-impl.h | 6 ++++ > include/qemu/target-info-init.h | 29 +++++++++++++--- > target-info-def.c | 61 +++++++++++++++++++++++++-------- > target-info-qom.c | 33 ++++++++++++++---- > 4 files changed, 104 insertions(+), 25 deletions(-) > > diff --git a/include/qemu/target-info-impl.h b/include/qemu/target-info-impl.h > index de329ec2b86..b4222e4455e 100644 > --- a/include/qemu/target-info-impl.h > +++ b/include/qemu/target-info-impl.h > @@ -23,6 +23,12 @@ typedef struct TargetInfo { > const char *cpu_type; > /* related to TARGET_BIG_ENDIAN definition */ > EndianMode endianness; > + /* > + * True on the endian variant that matches this translation unit's > + * TARGET_BIG_ENDIAN. target_info_qom_set_target() uses this when > + * more than one TargetInfo is registered and -target is omitted. > + */ > + bool is_default; > /* > * runtime equivalent of > * TARGET_PAGE_BITS_VARY ? TARGET_PAGE_BITS_LEGACY : TARGET_PAGE_BITS > diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h > index b7024c9faef..25d00adcc66 100644 > --- a/include/qemu/target-info-init.h > +++ b/include/qemu/target-info-init.h > @@ -37,15 +37,34 @@ const TargetInfo *target_info(void) \ > #include "qemu/target-info-qom.h" > #include "qom/object.h" > > -#define target_info_init(ti_var) \ > -static const TypeInfo target_info_qom_target_type_info = { \ > - .name = TYPE_TARGET_INFO"-"TARGET_NAME, \ > +/* > + * QOM type names are target-info-<TARGET_NAME>-le and -be so both > + * endian variants can be registered from one system translation unit. > + */ > +#define TARGET_INFO_QOM_SUFFIX_0 "-le" > +#define TARGET_INFO_QOM_SUFFIX_1 "-be" > + > +#define TARGET_INFO_QOM_NAME(sel) \ > + TYPE_TARGET_INFO "-" TARGET_NAME glue(TARGET_INFO_QOM_SUFFIX_, sel) > + > +#define TARGET_INFO_QOM_TYPEINFO(ti_var, sel) \ > +static const TypeInfo glue(target_info_qom_type_, sel) = { \ > + .name = TARGET_INFO_QOM_NAME(sel), \ > .parent = TYPE_TARGET_INFO, \ > .instance_size = sizeof(TargetInfoQom), \ > .class_size = sizeof(TargetInfoQomClass), \ > .class_data = &ti_var, \ > -}; \ > -DEFINE_TARGET_INFO_TYPE(target_info_qom_target_type_info) > +} > + > +#define target_info_init_le_be(ti_le, ti_be) \ > +TARGET_INFO_QOM_TYPEINFO(ti_le, 0); \ > +TARGET_INFO_QOM_TYPEINFO(ti_be, 1); \ > +static void do_qemu_init_target_info(void) \ > +{ \ > + type_register_static(&target_info_qom_type_0); \ > + type_register_static(&target_info_qom_type_1); \ > +} \ > +module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO) > > #endif /* CONFIG_USER_ONLY */ > #endif /* COMPILING_PER_TARGET */ > diff --git a/target-info-def.c b/target-info-def.c > index 5d38e405735..6722c43a08f 100644 > --- a/target-info-def.c > +++ b/target-info-def.c > @@ -28,39 +28,72 @@ QEMU_BUILD_BUG_ON(offsetof(ArchCPU, env) != sizeof(CPUState)); > QEMU_BUILD_BUG_ON(TARGET_PAGE_BITS < TARGET_PAGE_BITS_MIN); > #endif > > -static const TargetInfo target_info_def = { > - .target_name = TARGET_NAME, > - .target_arch = glue(SYS_EMU_TARGET_, TARGET_ARCH), > - .long_bits = TARGET_LONG_BITS, > - .cpu_type = CPU_RESOLVING_TYPE, > - .endianness = TARGET_BIG_ENDIAN ? ENDIAN_MODE_BIG : ENDIAN_MODE_LITTLE, > #ifdef TARGET_PAGE_BITS_VARY > - .page_bits_vary = true, > # ifdef TARGET_PAGE_BITS_LEGACY > +# define TARGET_INFO_PAGE_BITS \ > + .page_bits_vary = true, \ > .page_bits_init = TARGET_PAGE_BITS_LEGACY, > +# else > +# define TARGET_INFO_PAGE_BITS \ > + .page_bits_vary = true, > # endif > #else > - .page_bits_vary = false, > +# define TARGET_INFO_PAGE_BITS \ > + .page_bits_vary = false, \ > .page_bits_init = TARGET_PAGE_BITS, > #endif > > #ifndef CONFIG_USER_ONLY > # ifdef CONFIG_MULTIPROCESS > - .config_multiprocess = true, > +# define TARGET_INFO_CONFIG_MULTIPROCESS .config_multiprocess = true, > # else > - .config_multiprocess = false, > +# define TARGET_INFO_CONFIG_MULTIPROCESS .config_multiprocess = false, > # endif > # ifdef CONFIG_NITRO > - .config_nitro = true, > +# define TARGET_INFO_CONFIG_NITRO .config_nitro = true, > # else > - .config_nitro = false, > +# define TARGET_INFO_CONFIG_NITRO .config_nitro = false, > # endif > # ifdef CONFIG_XEN > - .config_xen = true, > +# define TARGET_INFO_CONFIG_XEN .config_xen = true, > # else > - .config_xen = false, > +# define TARGET_INFO_CONFIG_XEN .config_xen = false, > # endif > +# define TARGET_INFO_CONFIG \ > + TARGET_INFO_CONFIG_MULTIPROCESS \ > + TARGET_INFO_CONFIG_NITRO \ > + TARGET_INFO_CONFIG_XEN > +#else > +# define TARGET_INFO_CONFIG > #endif > + > +#define TARGET_INFO_COMMON \ > + .target_name = TARGET_NAME, \ > + .target_arch = glue(SYS_EMU_TARGET_, TARGET_ARCH), \ > + .long_bits = TARGET_LONG_BITS, \ > + .cpu_type = CPU_RESOLVING_TYPE, \ > + TARGET_INFO_PAGE_BITS \ > + TARGET_INFO_CONFIG > + > +#ifdef CONFIG_USER_ONLY > +static const TargetInfo target_info_def = { > + TARGET_INFO_COMMON > + .endianness = TARGET_BIG_ENDIAN ? ENDIAN_MODE_BIG : ENDIAN_MODE_LITTLE, > }; > > target_info_init(target_info_def) > +#else > +static const TargetInfo target_info_le = { > + TARGET_INFO_COMMON > + .endianness = ENDIAN_MODE_LITTLE, > + .is_default = !TARGET_BIG_ENDIAN, > +}; > + > +static const TargetInfo target_info_be = { > + TARGET_INFO_COMMON > + .endianness = ENDIAN_MODE_BIG, > + .is_default = TARGET_BIG_ENDIAN, > +}; > + > +target_info_init_le_be(target_info_le, target_info_be) > +#endif > diff --git a/target-info-qom.c b/target-info-qom.c > index 68ad734049c..2c1c57b05fd 100644 > --- a/target-info-qom.c > +++ b/target-info-qom.c > @@ -90,13 +90,34 @@ const TargetInfo *target_info(void) > void target_info_qom_set_target(void) > { > g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false); > - > + const TargetInfo *chosen = NULL; > size_t num_found = g_slist_length(targets); > - if (num_found != 1) { > - error_setg(&error_fatal, num_found == 0 ? > - "no target-info is available" : > - "more than one target-info is available"); > + size_t num_default = 0; > + > + if (num_found == 0) { > + error_setg(&error_fatal, "no target-info is available"); > + } > + > + if (num_found == 1) { > + target_info_ptr = TARGET_INFO_CLASS(targets->data)->target_info; > + return; > + } > + > + for (GSList *l = targets; l; l = l->next) { > + const TargetInfo *ti = TARGET_INFO_CLASS(l->data)->target_info; > + > + if (ti->is_default) { > + num_default++; > + chosen = ti; > + } > + } > + > + if (num_default != 1) { > + error_setg(&error_fatal, num_default == 0 ? > + "no default target-info is available" : > + "more than one default target-info " > + "is available"); > } > > - target_info_ptr = TARGET_INFO_CLASS(targets->data)->target_info; > + target_info_ptr = chosen; > } Is it representing existing targets, or adding new ones per endianness? I'm not sure if the goal is to add new binaries, or mimic existing ones with specific parameters.