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. Signed-off-by: Pierrick Bouvier <[email protected]> --- include/qemu/target-info-init.h | 48 +++++++++++++++++++++++++++++++++ include/qemu/target-info-qom.h | 23 ++++++++++++++++ target-info-qom.c | 10 +++++++ 3 files changed, 81 insertions(+) create mode 100644 include/qemu/target-info-qom.h diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h index 9be06d8523a..f3cea985540 100644 --- a/include/qemu/target-info-init.h +++ b/include/qemu/target-info-init.h @@ -11,10 +11,58 @@ #ifndef TARGET_INFO_DEF_H +#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_TYPES(target_info_qom_target_type_info) + +#endif /* CONFIG_USER_ONLY */ + #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..db069db718a --- /dev/null +++ b/include/qemu/target-info-qom.h @@ -0,0 +1,23 @@ +/* + * QEMU target info QOM types + * + * Copyright (c) Qualcomm + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#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) diff --git a/target-info-qom.c b/target-info-qom.c index 7fd58d24818..5ce29f80301 100644 --- a/target-info-qom.c +++ b/target-info-qom.c @@ -7,10 +7,20 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "qom/object.h" +#include "qemu/target-info-impl.h" +#include "qemu/target-info-qom.h" #include "hw/arm/machines-qom.h" static const TypeInfo target_info_types[] = { + { + .name = TYPE_TARGET_INFO, + .parent = TYPE_OBJECT, + .instance_size = sizeof(TargetInfoQom), + .class_size = sizeof(TargetInfoQomClass), + .abstract = true, + }, { .name = TYPE_TARGET_ARM_MACHINE, .parent = TYPE_INTERFACE, -- 2.43.0
