The combined qemu-system binary can select a registered target by name, or stay on SYS_EMU_TARGET_NONE. A single-target binary does not switch target.
The none entry is the same target-info-def.c stub as other targets, compiled with TARGET_BASE_ARCH NONE. target/none/cpu.h supplies ArchCPU for that stub, and cpu-param.h sets TARGET_VIRT_ADDR_SPACE_BITS. TYPE_NONE_CPU is NULL because there is no none CPU QOM type. type_register_internal() keeps types on the combined binary and filters them with TypeInfo.is_available. A single-target binary still omits types that cannot run. Signed-off-by: Yonggang Luo <[email protected]> --- include/qemu/target-info-select.h | 24 +++++++++++++++++++++ meson.build | 35 +++++++++++++++++++++++++++++++ qom/object.c | 8 ++++++- stubs/meson.build | 1 + stubs/target-info-select.c | 14 +++++++++++++ system/target-info-select.c | 26 +++++++++++++++++++++++ target/none/cpu-param.h | 7 +++++++ target/none/cpu-qom.h | 6 ++++++ target/none/cpu.h | 18 ++++++++++++++++ 9 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 include/qemu/target-info-select.h create mode 100644 stubs/target-info-select.c create mode 100644 system/target-info-select.c create mode 100644 target/none/cpu-param.h create mode 100644 target/none/cpu-qom.h create mode 100644 target/none/cpu.h diff --git a/include/qemu/target-info-select.h b/include/qemu/target-info-select.h new file mode 100644 index 00000000000..0659bb47567 --- /dev/null +++ b/include/qemu/target-info-select.h @@ -0,0 +1,24 @@ +#ifndef QEMU_TARGET_INFO_SELECT_H +#define QEMU_TARGET_INFO_SELECT_H + +/** + * target_combined_binary: + * + * Returns: %true if this is the combined qemu-system binary. + */ +bool target_combined_binary(void); + +typedef struct Error Error; + +/** + * target_info_select_by_name: + * @name: target_name to select, or NULL + * @errp: error location + * + * Combined qemu-system only. NULL selects "none". Every name, including + * "none", is looked up in target_info_list(). The stub is a no-op on + * single-target binaries. + */ +void target_info_select_by_name(const char *name, Error **errp); + +#endif diff --git a/meson.build b/meson.build index 7ab5c7971a8..96f493cb746 100644 --- a/meson.build +++ b/meson.build @@ -4618,6 +4618,41 @@ if single_binary_available endforeach single_binary_objects += single_binary_target_info_objects + none_config_target_data = configuration_data() + none_config_target_data.set_quoted('TARGET_NAME', 'none') + none_config_target_data.set('TARGET_ARCH', 'NONE') + none_config_target_data.set('TARGET_BASE_ARCH', 'NONE') + none_config_target_data.set('TARGET_LONG_BITS', 64) + none_config_target_data.set('TARGET_BIG_ENDIAN', 0) + none_config_target_h = configure_file(output: 'none-config-target.h', + configuration: none_config_target_data) + none_config_devices_data = configuration_data() + foreach k, v : single_binary_config + if v == 'y' + none_config_devices_data.set(k, 1) + endif + endforeach + none_config_devices_h = configure_file(output: 'none-config-devices.h', + configuration: none_config_devices_data) + qemu_none_ss = ss.source_set() + qemu_none_ss.add(files('system/target-info-select.c')) + qemu_none_ss.add(target_info_def) + qemu_none_src = qemu_none_ss.apply(single_binary_config, strict: false) + qemu_none = static_library('qemu-none', + sources: qemu_none_src.sources() + genh + + [none_config_target_h, + none_config_devices_h], + dependencies: qemu_none_src.dependencies(), + include_directories: include_directories( + 'target' / 'none'), + c_args: [ + '-DCOMPILING_PER_TARGET', + '-DCONFIG_TARGET="none-config-target.h"', + '-DCONFIG_DEVICES="none-config-devices.h"', + ], + build_by_default: false) + single_binary_objects += qemu_none.extract_objects(qemu_none_src.sources()) + single_binary_link_args = emulator_link_args single_binary_link_args += enable_modules ? ['@block.syms', '@qemu.syms'] : [] qemu_system_name = 'qemu-system' diff --git a/qom/object.c b/qom/object.c index 76b0b0806b3..2ce6c369df5 100644 --- a/qom/object.c +++ b/qom/object.c @@ -16,6 +16,7 @@ #include "qom/object.h" #include "qom/object_interfaces.h" #include "qemu/target-info-qapi.h" +#include "qemu/target-info-select.h" #include "qemu/cutils.h" #include "qemu/memalign.h" #include "qapi/visitor.h" @@ -171,7 +172,12 @@ static TypeImpl *type_register_internal(const TypeInfo *info) abort(); } - if (info->is_available && !info->is_available(target_info())) { + /* + * Single-target binaries omit types that cannot run. The combined + * binary keeps them and filters with is_available per target. + */ + if (!target_combined_binary() && info->is_available && + !info->is_available(target_info())) { return NULL; } diff --git a/stubs/meson.build b/stubs/meson.build index 29b6644b254..3765537778d 100644 --- a/stubs/meson.build +++ b/stubs/meson.build @@ -3,6 +3,7 @@ # below, so that it is clear who needs the stubbed functionality. stub_ss.add(files('cpu-get-clock.c')) +stub_ss.add(files('target-info-select.c')) stub_ss.add(files('fdset.c')) stub_ss.add(files('iothread-lock.c')) stub_ss.add(files('is-daemonized.c')) diff --git a/stubs/target-info-select.c b/stubs/target-info-select.c new file mode 100644 index 00000000000..5c9e8dc6e19 --- /dev/null +++ b/stubs/target-info-select.c @@ -0,0 +1,14 @@ +#include "qemu/osdep.h" +#include "qemu/target-info-select.h" +#include "qapi/error.h" + +bool target_combined_binary(void) +{ + return false; +} + +void target_info_select_by_name(const char *name, Error **errp) +{ + (void)name; + (void)errp; +} diff --git a/system/target-info-select.c b/system/target-info-select.c new file mode 100644 index 00000000000..4b4a9fdf256 --- /dev/null +++ b/system/target-info-select.c @@ -0,0 +1,26 @@ +#include "qemu/osdep.h" +#include "qemu/target-info-def.h" +#include "qemu/target-info-select.h" +#include "qapi/error.h" + +bool target_combined_binary(void) +{ + return true; +} + +void target_info_select_by_name(const char *name, Error **errp) +{ + TargetInfoNode *node; + + if (!name) { + name = "none"; + } + + QLIST_FOREACH(node, target_info_list(), next) { + if (!strcmp(name, node->info->target_name)) { + target_info_select(node->info); + return; + } + } + error_setg(errp, "target '%s' is not available", name); +} diff --git a/target/none/cpu-param.h b/target/none/cpu-param.h new file mode 100644 index 00000000000..3c0818a2f02 --- /dev/null +++ b/target/none/cpu-param.h @@ -0,0 +1,7 @@ +#ifndef NONE_CPU_PARAM_H +#define NONE_CPU_PARAM_H + +#define TARGET_PAGE_BITS 9 +#define TARGET_VIRT_ADDR_SPACE_BITS 64 + +#endif diff --git a/target/none/cpu-qom.h b/target/none/cpu-qom.h new file mode 100644 index 00000000000..114faa8077a --- /dev/null +++ b/target/none/cpu-qom.h @@ -0,0 +1,6 @@ +#ifndef QEMU_NONE_CPU_QOM_H +#define QEMU_NONE_CPU_QOM_H + +#define TYPE_NONE_CPU NULL + +#endif diff --git a/target/none/cpu.h b/target/none/cpu.h new file mode 100644 index 00000000000..ffb9a0d28dc --- /dev/null +++ b/target/none/cpu.h @@ -0,0 +1,18 @@ +#ifndef QEMU_NONE_CPU_H +#define QEMU_NONE_CPU_H + +#include "cpu-qom.h" +#include "hw/core/cpu.h" + +#define CPU_RESOLVING_TYPE TYPE_NONE_CPU + +typedef struct CPUArchState { + uint64_t unused; +} CPUArchState; + +struct ArchCPU { + CPUState parent_obj; + CPUArchState env; +}; + +#endif -- 2.52.0.windows.1
