Change TypeInfo.is_available to TypeIsAvailable taking const TargetInfo *. Store the callback on TypeImpl. object_class_get_is_available() returns that callback, or target_is_any() when the class has none.
Signed-off-by: Yonggang Luo <[email protected]> --- hw/arm/aspeed_ast27x0-fc.c | 2 +- hw/arm/aspeed_ast27x0_evb.c | 4 ++-- hw/arm/raspi.c | 4 ++-- hw/arm/raspi4b.c | 2 +- include/qom/object.h | 26 +++++++++++++++++++++++--- qom/object.c | 14 +++++++++++++- 6 files changed, 42 insertions(+), 10 deletions(-) diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c index 73362b60d2a..8a7c6a116ac 100644 --- a/hw/arm/aspeed_ast27x0-fc.c +++ b/hw/arm/aspeed_ast27x0-fc.c @@ -234,7 +234,7 @@ static const TypeInfo ast2700fc_types[] = { .parent = TYPE_MACHINE, .class_init = ast2700fc_class_init, .instance_size = sizeof(Ast2700FCState), - .is_available = target_aarch64, + .is_available = target_is_aarch64, }, }; diff --git a/hw/arm/aspeed_ast27x0_evb.c b/hw/arm/aspeed_ast27x0_evb.c index 460c9ff0d2e..02a8cff1d9d 100644 --- a/hw/arm/aspeed_ast27x0_evb.c +++ b/hw/arm/aspeed_ast27x0_evb.c @@ -75,13 +75,13 @@ static const TypeInfo aspeed_ast27x0_evb_types[] = { .name = MACHINE_TYPE_NAME("ast2700a1-evb"), .parent = TYPE_ASPEED_MACHINE, .class_init = aspeed_machine_ast2700a1_evb_class_init, - .is_available = target_aarch64, + .is_available = target_is_aarch64, }, { .name = MACHINE_TYPE_NAME("ast2700a2-evb"), .parent = TYPE_ASPEED_MACHINE, .class_init = aspeed_machine_ast2700a2_evb_class_init, - .is_available = target_aarch64, + .is_available = target_is_aarch64, } }; diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index fadbacb2534..22b06c6ca22 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -403,12 +403,12 @@ static const TypeInfo raspi_machine_types[] = { .name = MACHINE_TYPE_NAME("raspi3ap"), .parent = TYPE_RASPI_MACHINE, .class_init = raspi3ap_machine_class_init, - .is_available = target_aarch64, + .is_available = target_is_aarch64, }, { .name = MACHINE_TYPE_NAME("raspi3b"), .parent = TYPE_RASPI_MACHINE, .class_init = raspi3b_machine_class_init, - .is_available = target_aarch64, + .is_available = target_is_aarch64, }, { .name = TYPE_RASPI_MACHINE, .parent = TYPE_RASPI_BASE_MACHINE, diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c index 566d64572db..a1dc477f25e 100644 --- a/hw/arm/raspi4b.c +++ b/hw/arm/raspi4b.c @@ -121,7 +121,7 @@ static const TypeInfo raspi4b_machine_type = { .parent = TYPE_RASPI_BASE_MACHINE, .instance_size = sizeof(Raspi4bMachineState), .class_init = raspi4b_machine_class_init, - .is_available = target_aarch64, + .is_available = target_is_aarch64, }; static void raspi4b_machine_register_type(void) diff --git a/include/qom/object.h b/include/qom/object.h index 4c0645817a5..3791f335fdb 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -16,6 +16,7 @@ #include "qapi/qapi-builtin-types.h" #include "qemu/module.h" +#include "qemu/target-info.h" struct TypeImpl; typedef struct TypeImpl *Type; @@ -117,6 +118,15 @@ typedef void (ObjectUnparent)(Object *obj); */ typedef void (ObjectFree)(void *obj); +/** + * typedef TypeIsAvailable: + * @ti: TargetInfo to test. + * + * Returns whether a type is available for @ti. Typical implementations + * are target_is_*(). + */ +typedef bool (TypeIsAvailable)(const TargetInfo *ti); + #define OBJECT_CLASS_CAST_CACHE 4 /** @@ -473,8 +483,10 @@ struct Object * @class_data: Data to pass to the @class_init, * @class_base_init. This can be useful when building dynamic * classes. - * @is_available: callback invoked at registration time, to dynamically check if - * this type should be available or not. + * @is_available: Optional callback. Unset inherits the parent type's + * callback in the MODULE_INIT_QOM after pass (parents are not all + * registered at type_register time). After inherit the callback is + * never NULL. Callers may also invoke it with a chosen TargetInfo. * @interfaces: The list of interfaces associated with this type. This * should point to a static array that's terminated with a zero filled * element. @@ -498,7 +510,7 @@ struct TypeInfo void (*class_base_init)(ObjectClass *klass, const void *data); const void *class_data; - bool (*is_available)(void); + TypeIsAvailable *is_available; const InterfaceInfo *interfaces; }; @@ -1087,6 +1099,14 @@ bool object_class_is_abstract(ObjectClass *klass); */ bool object_class_is_secure(ObjectClass *klass); +/** + * object_class_get_is_available: + * @klass: The class to obtain TypeInfo.is_available for. + * + * Returns: The class is_available callback, never %NULL. + */ +TypeIsAvailable *object_class_get_is_available(ObjectClass *klass); + /** * object_class_by_name: * @typename: The QOM typename to obtain the class for. diff --git a/qom/object.c b/qom/object.c index 96498f3d001..76b0b0806b3 100644 --- a/qom/object.c +++ b/qom/object.c @@ -15,6 +15,7 @@ #include "qom/compat-properties.h" #include "qom/object.h" #include "qom/object_interfaces.h" +#include "qemu/target-info-qapi.h" #include "qemu/cutils.h" #include "qemu/memalign.h" #include "qapi/visitor.h" @@ -71,6 +72,8 @@ struct TypeImpl bool abstract; bool secure; + TypeIsAvailable *is_available; + const char *parent; TypeImpl *parent_type; @@ -126,6 +129,7 @@ static TypeImpl *type_new(const TypeInfo *info) ti->abstract = info->abstract; ti->secure = info->secure; + ti->is_available = info->is_available; for (i = 0; info->interfaces && info->interfaces[i].type; i++) { ti->interfaces[i].typename = g_strdup(info->interfaces[i].type); @@ -167,7 +171,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info) abort(); } - if (info->is_available && !info->is_available()) { + if (info->is_available && !info->is_available(target_info())) { return NULL; } @@ -1153,6 +1157,14 @@ bool object_class_is_secure(ObjectClass *klass) return klass->type->secure; } +TypeIsAvailable *object_class_get_is_available(ObjectClass *klass) +{ + if (klass->type->is_available) { + return klass->type->is_available; + } + return target_is_any; +} + const char *object_class_get_name(ObjectClass *klass) { return klass->type->name; -- 2.52.0.windows.1
