For the single-binary, we want to be able to retrieve at runtime the current target among the different ones available. A consequence is that we can't rely on existing target_info() definition since it will create a conflict once more than one target is available.
To solve this, we add TargetInfo in QOM, with this hierarchy. We define one class "target-info-X" per target, that inherits from abstract class "target-info". Using concrete vs abstract class ensure we can easily filter "target-info-X" from all QOM types. Associated TargetInfo is directly set through class initialization, without relying on any instance. For user mode, we simply define target_info() like it was done previously. In this patch, we keep the same definition for system-mode also, and it will be replaced in next commits. We will introduce detection of target from QOM, so we need to make sure those types are registered early. Signed-off-by: Pierrick Bouvier <[email protected]> --- include/qemu/module.h | 1 + include/qemu/target-info-init.h | 57 +++++++++++++++++++++++++++++++++ include/qemu/target-info-qom.h | 28 ++++++++++++++++ system/vl.c | 2 ++ target-info-qom.c | 14 ++++++++ 5 files changed, 102 insertions(+) create mode 100644 include/qemu/target-info-qom.h diff --git a/include/qemu/module.h b/include/qemu/module.h index 9885ac9afb3..fccf017bf9e 100644 --- a/include/qemu/module.h +++ b/include/qemu/module.h @@ -43,6 +43,7 @@ typedef enum { MODULE_INIT_MIGRATION, MODULE_INIT_BLOCK, MODULE_INIT_OPTS, + MODULE_INIT_TARGET_INFO, MODULE_INIT_QOM, MODULE_INIT_TRACE, MODULE_INIT_XEN_BACKEND, diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h index c781cfc0590..859451c672e 100644 --- a/include/qemu/target-info-init.h +++ b/include/qemu/target-info-init.h @@ -12,10 +12,67 @@ #ifndef TARGET_INFO_DEF_H #define TARGET_INFO_DEF_H +#define DEFINE_TARGET_INFO_TYPE(info) \ +static void do_qemu_init_target_info(void) \ +{ \ + type_register_static(&info); \ +} \ +module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO) + +#ifdef COMPILING_PER_TARGET +#ifdef CONFIG_USER_ONLY + +/* + * User mode does not support multiple targets in the same binary, so just + * define target_info(). + */ #define target_info_init(ti_var) \ const TargetInfo *target_info(void) \ { \ return &ti_var; \ } +#else /* CONFIG_USER_ONLY */ + +#include "qemu/target-info-qom.h" +#include "qom/object.h" + +#define TYPE_TARGET_INFO_TARGET TYPE_TARGET_INFO"-"TARGET_NAME + +typedef struct TargetInfoQomTarget { + TargetInfoQom parent; +} TargetInfoQomTarget; + +typedef struct TargetInfoQomTargetClass { + TargetInfoQomClass parent_class; +} TargetInfoQomTargetClass; + +OBJECT_DECLARE_TYPE(TargetInfoQomTarget, TargetInfoQomTargetClass, TARGET_INFO_TARGET) + +#define target_info_init(ti_var) \ +const TargetInfo *target_info(void) \ +{ \ + return &ti_var; \ +} \ + \ +static void target_info_qom_class_init(ObjectClass *oc, const void * data) \ +{ \ + TargetInfoQomTargetClass *klass = TARGET_INFO_TARGET_CLASS(oc); \ + klass->parent_class.target_info = &ti_var; \ +} \ + \ +static const TypeInfo target_info_qom_target_type_info = { \ + .name = TYPE_TARGET_INFO_TARGET, \ + .parent = TYPE_TARGET_INFO, \ + .instance_size = sizeof(TargetInfoQomTarget), \ + .class_size = sizeof(TargetInfoQomTargetClass), \ + .class_init = target_info_qom_class_init, \ + .abstract = false, \ +}; \ + \ +DEFINE_TARGET_INFO_TYPE(target_info_qom_target_type_info) + +#endif /* CONFIG_USER_ONLY */ +#endif /* COMPILING_PER_TARGET */ + #endif /* TARGET_INFO_DEF_H */ diff --git a/include/qemu/target-info-qom.h b/include/qemu/target-info-qom.h new file mode 100644 index 00000000000..585995c7ad0 --- /dev/null +++ b/include/qemu/target-info-qom.h @@ -0,0 +1,28 @@ +/* + * QEMU target info QOM types + * + * Copyright (c) Qualcomm + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef QEMU_TARGET_INFO_QOM_H +#define QEMU_TARGET_INFO_QOM_H + +#include "qemu/target-info-impl.h" +#include "qom/object.h" + +#define TYPE_TARGET_INFO "target-info" + +typedef struct TargetInfoQom { + Object parent_obj; +} TargetInfoQom; + +typedef struct TargetInfoQomClass { + ObjectClass parent_class; + const TargetInfo *target_info; +} TargetInfoQomClass; + +OBJECT_DECLARE_TYPE(TargetInfoQom, TargetInfoQomClass, TARGET_INFO) + +#endif /* QEMU_TARGET_INFO_QOM_H */ diff --git a/system/vl.c b/system/vl.c index 516ed7890b4..2b6739271ba 100644 --- a/system/vl.c +++ b/system/vl.c @@ -2890,6 +2890,8 @@ void qemu_init(int argc, char **argv) os_setup_limits(); + module_call_init(MODULE_INIT_TARGET_INFO); + module_init_info(qemu_modinfo); module_allow_arch(target_name()); diff --git a/target-info-qom.c b/target-info-qom.c index 7fd58d24818..ba2c7923760 100644 --- a/target-info-qom.c +++ b/target-info-qom.c @@ -7,7 +7,11 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qom/object.h" +#include "qemu/target-info-impl.h" +#include "qemu/target-info-init.h" +#include "qemu/target-info-qom.h" #include "hw/arm/machines-qom.h" static const TypeInfo target_info_types[] = { @@ -22,3 +26,13 @@ static const TypeInfo target_info_types[] = { }; DEFINE_TYPES(target_info_types) + +static const TypeInfo target_info_parent_type = { + .name = TYPE_TARGET_INFO, + .parent = TYPE_OBJECT, + .instance_size = sizeof(TargetInfoQom), + .class_size = sizeof(TargetInfoQomClass), + .abstract = true, +}; + +DEFINE_TARGET_INFO_TYPE(target_info_parent_type) -- 2.43.0
