[PATCH 11/12] target-info: dispatch CPU QMP, dump, and Angel semihosting
Yonggang Luo <[email protected]>
| Newsgroups | org.nongnu.qemu-devel,org.nongnu.qemu-arm,org.nongnu.qemu-riscv |
|---|---|
| Message-ID | <[email protected]> |
- Combined binaries cannot keep one global C symbol per arch for query-cpu-definitions, dump notes, or Angel semihosting. Put those handlers on a process-wide TargetCpuOps table and fill one member at a time. - TARGET_INFO_CPU_OP is type_init (MODULE_INIT_QOM). That runs after target_info_qom_set_target(), so ELF constructors only queue the callback. target_info_register_cpu_op() stores the impl only when cpu_type matches the selected TargetInfo; a duplicate slot is reported and ignored. A NULL member means this target has no handler, not "too early". - Keep the table in target-info.c (common_ss) and filter with target_info()->cpu_type so user-mode can resolve TARGET_INFO_CPU_OP. Take the address of the impl so the same macro stores both function pointers and ops tables. - QMP query-cpu-definitions and query-cpu-model-expansion dispatch from hw/core/machine-qmp-cmds.c. Dump cpu_get_dump_info and cpu_get_note_size dispatch from hw/core/cpu-system.c. Arch handlers are static with an arch prefix (s390_query_*, arm_get_dump_info, ...). ppc and mips drop expansion stubs; the dispatcher errors instead. - Angel semihosting uses CPUSemihostingOps on TargetCpuOps.semihosting. ARM and RISC-V keep a static ops table in common-semi-target.c and register it with TARGET_INFO_CPU_OP. Wrappers in common-semi.h call target_info_cpu_ops()->semihosting. Always compile those files so both tables exist in a combined link. - Drop stubs/qmp-cpu.c and stubs/dump.c: every system binary has the wrappers, and tools do not implement these commands. Keep stubs/qmp-cpu-s390x.c for comparison/baseline. Signed-off-by: Yonggang Luo <[email protected]> --- MAINTAINERS | 1 - hw/core/cpu-system.c | 23 +++++++++++ hw/core/machine-qmp-cmds.c | 26 +++++++++++++ include/qemu/target-info-qom.h | 41 ++++++++++++++++++++ include/semihosting/common-semi.h | 56 ++++++++++++++++++++++++--- stubs/dump.c | 27 ------------- stubs/meson.build | 2 - stubs/qmp-cpu.c | 21 ---------- target-info.c | 32 +++++++++++++++ target/arm/arch_dump.c | 8 +++- target/arm/arm-qmp-cmds.c | 15 +++++-- target/arm/common-semi-target.c | 23 ++++++++--- target/arm/meson.build | 7 +--- target/i386/arch_dump.c | 8 +++- target/i386/cpu-system.c | 12 ++++-- target/i386/cpu.c | 6 ++- target/loongarch/arch_dump.c | 8 +++- target/loongarch/loongarch-qmp-cmds.c | 15 +++++-- target/mips/system/mips-qmp-cmds.c | 15 +++---- target/ppc/arch_dump.c | 8 +++- target/ppc/ppc-qmp-cmds.c | 15 +++---- target/riscv/arch_dump.c | 8 +++- target/riscv/common-semi-target.c | 25 ++++++++---- target/riscv/meson.build | 4 +- target/riscv/riscv-qmp-cmds.c | 15 +++++-- target/s390x/arch_dump.c | 8 +++- target/s390x/cpu_models_system.c | 15 +++++-- 27 files changed, 313 insertions(+), 131 deletions(-) delete mode 100644 stubs/dump.c delete mode 100644 stubs/qmp-cpu.c diff --git a/MAINTAINERS b/MAINTAINERS index 902db77218e..08e84e4ac6d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3348,7 +3348,6 @@ F: include/system/dump-arch.h F: include/system/dump.h F: qapi/dump.json F: scripts/dump-guest-memory.py -F: stubs/dump.c F: docs/specs/vmcoreinfo.rst F: tests/qtest/vmcoreinfo-test.c F: tests/qtest/dump-test.c diff --git a/hw/core/cpu-system.c b/hw/core/cpu-system.c index 14eb4ed87f8..6dfbbac7f24 100644 --- a/hw/core/cpu-system.c +++ b/hw/core/cpu-system.c @@ -24,7 +24,9 @@ #include "exec/cputlb.h" #include "exec/target_page.h" #include "system/memory.h" +#include "system/dump-arch.h" #include "qemu/target-info.h" +#include "qemu/target-info-qom.h" #include "hw/core/qdev.h" #include "hw/core/qdev-properties.h" #include "hw/core/sysemu-cpu-ops.h" @@ -127,6 +129,27 @@ int cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, return (*cpu->cc->sysemu_ops->write_elf64_note)(f, cpu, cpuid, opaque); } +int cpu_get_dump_info(ArchDumpInfo *info, + const struct GuestPhysBlockList *guest_phys_blocks) +{ + const TargetCpuOps *ops = target_info_cpu_ops(); + + if (!ops->get_dump_info) { + return -1; + } + return ops->get_dump_info(info, guest_phys_blocks); +} + +ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) +{ + const TargetCpuOps *ops = target_info_cpu_ops(); + + if (!ops->get_note_size) { + return -1; + } + return ops->get_note_size(class, machine, nr_cpus); +} + bool cpu_internal_is_big_endian(CPUState *cpu) { if (cpu->cc->sysemu_ops->internal_is_big_endian) { diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c index e6e6ecc31e3..f8297203848 100644 --- a/hw/core/machine-qmp-cmds.c +++ b/hw/core/machine-qmp-cmds.c @@ -449,3 +449,29 @@ void qmp_dump_skeys(const char *filename, Error **errp) } DUMP_SKEYS_INTERFACE_CLASS(oc)->qmp_dump_skeys(filename, errp); } + +CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) +{ + const TargetCpuOps *ops = target_info_cpu_ops(); + + if (!ops->query_cpu_definitions) { + error_setg(errp, + "CPU model definitions are not supported on this target"); + return NULL; + } + return ops->query_cpu_definitions(errp); +} + +CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, + CpuModelInfo *model, + Error **errp) +{ + const TargetCpuOps *ops = target_info_cpu_ops(); + + if (!ops->query_cpu_model_expansion) { + error_setg(errp, + "CPU model expansion is not supported on this target"); + return NULL; + } + return ops->query_cpu_model_expansion(type, model, errp); +} diff --git a/include/qemu/target-info-qom.h b/include/qemu/target-info-qom.h index 3b59cf82d65..0f0f49faaa8 100644 --- a/include/qemu/target-info-qom.h +++ b/include/qemu/target-info-qom.h @@ -10,8 +10,12 @@ #define QEMU_TARGET_INFO_QOM_H #include "qemu/target-info-impl.h" +#include "qapi/error.h" +#include "qemu/compiler.h" #include "qom/object.h" +#include <stddef.h> + #define TYPE_TARGET_INFO "target-info" #define TYPE_TARGET_SPECIFIC "target-specific" @@ -40,6 +44,43 @@ typedef struct TargetInfoQomClass { OBJECT_DECLARE_TYPE(TargetInfoQom, TargetInfoQomClass, TARGET_INFO) +typedef struct ArchDumpInfo ArchDumpInfo; +struct GuestPhysBlockList; +typedef struct CPUSemihostingOps CPUSemihostingOps; + +typedef struct TargetCpuOps { + CpuDefinitionInfoList *(*query_cpu_definitions)(Error **errp); + CpuModelExpansionInfo *(*query_cpu_model_expansion)( + CpuModelExpansionType type, CpuModelInfo *model, Error **errp); + int (*get_dump_info)(ArchDumpInfo *info, + const struct GuestPhysBlockList *guest_phys_blocks); + ssize_t (*get_note_size)(int class, int machine, int nr_cpus); + const CPUSemihostingOps *semihosting; +} TargetCpuOps; + +/** + * target_info_register_cpu_op: + * @cpu_type: CPU_RESOLVING_TYPE of the registering architecture + * @offset: offsetof(TargetCpuOps, member) for the slot being filled + * @impl: handler or ops table stored at that offset + * + * Combined binaries merge one member at a time so QMP, dump, and + * semihosting (or split QMP files) can register independently. + * MODULE_INIT_QOM runs after target_info_qom_set_target(), so only + * the selected cpu_type is stored. + */ +void target_info_register_cpu_op(const char *cpu_type, size_t offset, + void *impl); +const TargetCpuOps *target_info_cpu_ops(void); + +#define TARGET_INFO_CPU_OP(cpu_type, member, impl) \ +static void glue(target_info_cpu_op_, impl)(void) \ +{ \ + target_info_register_cpu_op((cpu_type), offsetof(TargetCpuOps, member), \ + (void *)&(impl)); \ +} \ +type_init(glue(target_info_cpu_op_, impl)) + /** * target_info_qom_set_target: * @name: -target token, or NULL/%empty to infer from the program diff --git a/include/semihosting/common-semi.h b/include/semihosting/common-semi.h index aa511a46f42..f86a855a3dd 100644 --- a/include/semihosting/common-semi.h +++ b/include/semihosting/common-semi.h @@ -34,12 +34,56 @@ #ifndef COMMON_SEMI_H #define COMMON_SEMI_H +#include "exec/cpu-common.h" +#include "qemu/target-info-qom.h" + +typedef struct CPUSemihostingOps { + uint64_t (*arg)(CPUState *cs, int argno); + void (*set_ret)(CPUState *cs, uint64_t ret); + bool (*is_64bit)(CPUArchState *env); + bool (*sys_exit_is_extended)(CPUState *cs); + uint64_t (*stack_bottom)(CPUState *cs); + bool (*has_synccache)(CPUArchState *env); +} CPUSemihostingOps; + void do_common_semihosting(CPUState *cs); -uint64_t common_semi_arg(CPUState *cs, int argno); -void common_semi_set_ret(CPUState *cs, uint64_t ret); -bool is_64bit_semihosting(CPUArchState *env); -bool common_semi_sys_exit_is_extended(CPUState *cs); -uint64_t common_semi_stack_bottom(CPUState *cs); -bool common_semi_has_synccache(CPUArchState *env); + +static inline const CPUSemihostingOps *cpu_semihosting_ops(void) +{ + const CPUSemihostingOps *ops = target_info_cpu_ops()->semihosting; + + g_assert(ops); + return ops; +} + +static inline uint64_t common_semi_arg(CPUState *cs, int argno) +{ + return cpu_semihosting_ops()->arg(cs, argno); +} + +static inline void common_semi_set_ret(CPUState *cs, uint64_t ret) +{ + cpu_semihosting_ops()->set_ret(cs, ret); +} + +static inline bool is_64bit_semihosting(CPUArchState *env) +{ + return cpu_semihosting_ops()->is_64bit(env); +} + +static inline bool common_semi_sys_exit_is_extended(CPUState *cs) +{ + return cpu_semihosting_ops()->sys_exit_is_extended(cs); +} + +static inline uint64_t common_semi_stack_bottom(CPUState *cs) +{ + return cpu_semihosting_ops()->stack_bottom(cs); +} + +static inline bool common_semi_has_synccache(CPUArchState *env) +{ + return cpu_semihosting_ops()->has_synccache(env); +} #endif /* COMMON_SEMI_H */ diff --git a/stubs/dump.c b/stubs/dump.c deleted file mode 100644 index df7897b72b1..00000000000 --- a/stubs/dump.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * QEMU dump - * - * Copyright Fujitsu, Corp. 2011, 2012 - * - * Authors: - * Wen Congyang <[email protected]> - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - * - */ - -#include "qemu/osdep.h" -#include "system/dump-arch.h" - -int cpu_get_dump_info(ArchDumpInfo *info, - const struct GuestPhysBlockList *guest_phys_blocks) -{ - return -1; -} - -ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) -{ - return -1; -} - diff --git a/stubs/meson.build b/stubs/meson.build index 3b2f2680b19..94024aef868 100644 --- a/stubs/meson.build +++ b/stubs/meson.build @@ -68,7 +68,6 @@ if have_system # adding more of these. If the symbol is used in specific_ss, # in particular, consider defining a preprocessor macro via # Kconfig or configs/targets/. - stub_ss.add(files('dump.c')) stub_ss.add(files('cmos.c')) stub_ss.add(files('fw_cfg.c')) if igvm.found() @@ -82,7 +81,6 @@ if have_system stub_ss.add(files('qmp-i386-sev.c')) stub_ss.add(files('qmp-i386-sgx.c')) stub_ss.add(files('qmp-i386-xen.c')) - stub_ss.add(files('qmp-cpu.c')) stub_ss.add(files('qmp-cpu-s390x.c')) stub_ss.add(files('qmp-cpu-s390x-kvm.c')) stub_ss.add(files('hmp-cmd-info_mem.c')) diff --git a/stubs/qmp-cpu.c b/stubs/qmp-cpu.c deleted file mode 100644 index a8c7ee89b9d..00000000000 --- a/stubs/qmp-cpu.c +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "qapi/qapi-commands-machine.h" - -CpuModelExpansionInfo * -qmp_query_cpu_model_expansion(CpuModelExpansionType type, - CpuModelInfo *model, - Error **errp) -{ - error_setg(errp, "CPU model expansion is not supported on this target"); - return NULL; -} - -CpuDefinitionInfoList * -qmp_query_cpu_definitions(Error **errp) -{ - error_setg(errp, "CPU model definitions are not supported on this target"); - return NULL; -} diff --git a/target-info.c b/target-info.c index ce7f9797dce..aa4be08bb94 100644 --- a/target-info.c +++ b/target-info.c @@ -7,9 +7,11 @@ */ #include "qemu/osdep.h" +#include "qemu/error-report.h" #include "qemu/target-info.h" #include "qemu/target-info-qapi.h" #include "qemu/target-info-impl.h" +#include "qemu/target-info-qom.h" #include "qapi/error.h" const char *target_name(void) @@ -124,3 +126,33 @@ bool target_config_xen(void) { return target_info()->config_xen; } + +static TargetCpuOps target_cpu_ops; + +void target_info_register_cpu_op(const char *cpu_type, size_t offset, + void *impl) +{ + const TargetInfo *ti = target_info(); + void **slot; + + g_assert(ti); + g_assert(offset + sizeof(void *) <= sizeof(TargetCpuOps)); + g_assert((offset % sizeof(void *)) == 0); + + if (strcmp(cpu_type, ti->cpu_type)) { + return; + } + + slot = (void **)((char *)&target_cpu_ops + offset); + if (*slot) { + error_report("TargetCpuOps already registered for type '%s' (offset %zu)", + cpu_type, offset); + return; + } + *slot = impl; +} + +const TargetCpuOps *target_info_cpu_ops(void) +{ + return &target_cpu_ops; +} diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c index 1dd79849c13..e072516bdac 100644 --- a/target/arm/arch_dump.c +++ b/target/arm/arch_dump.c @@ -24,6 +24,7 @@ #include "system/dump.h" #include "cpu-features.h" #include "internals.h" +#include "qemu/target-info-qom.h" /* struct user_pt_regs from arch/arm64/include/uapi/asm/ptrace.h */ struct aarch64_user_regs { @@ -385,7 +386,7 @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs, return 0; } -int cpu_get_dump_info(ArchDumpInfo *info, +static int arm_get_dump_info(ArchDumpInfo *info, const GuestPhysBlockList *guest_phys_blocks) { ARMCPU *cpu; @@ -439,7 +440,7 @@ int cpu_get_dump_info(ArchDumpInfo *info, return 0; } -ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) +static ssize_t arm_get_note_size(int class, int machine, int nr_cpus) { ARMCPU *cpu = ARM_CPU(first_cpu); size_t note_size; @@ -459,3 +460,6 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) return note_size * nr_cpus; } + +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_dump_info, arm_get_dump_info); +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_note_size, arm_get_note_size); diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c index 83ec95c290f..c85bde5d79d 100644 --- a/target/arm/arm-qmp-cmds.c +++ b/target/arm/arm-qmp-cmds.c @@ -32,6 +32,7 @@ #include "qobject/qdict.h" #include "qom/qom-qobject.h" #include "cpu.h" +#include "qemu/target-info-qom.h" static GICCapability *gic_cap_new(int version) { @@ -79,9 +80,10 @@ static const char *cpu_model_advertised_features[] = { NULL }; -CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, - CpuModelInfo *model, - Error **errp) +static CpuModelExpansionInfo * +arm_query_cpu_model_expansion(CpuModelExpansionType type, + CpuModelInfo *model, + Error **errp) { CpuModelExpansionInfo *expansion_info; const QDict *qdict_in; @@ -216,7 +218,7 @@ static void arm_cpu_add_definition(gpointer data, gpointer user_data) QAPI_LIST_PREPEND(*cpu_list, info); } -CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) +static CpuDefinitionInfoList *arm_query_cpu_definitions(Error **errp) { CpuDefinitionInfoList *cpu_list = NULL; GSList *list; @@ -227,3 +229,8 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) return cpu_list; } + +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_definitions, + arm_query_cpu_definitions); +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_model_expansion, + arm_query_cpu_model_expansion); diff --git a/target/arm/common-semi-target.c b/target/arm/common-semi-target.c index 2b77ce9c17b..eccd3735df8 100644 --- a/target/arm/common-semi-target.c +++ b/target/arm/common-semi-target.c @@ -12,7 +12,7 @@ #include "semihosting/common-semi.h" #include "target/arm/cpu-qom.h" -uint64_t common_semi_arg(CPUState *cs, int argno) +static uint64_t arm_common_semi_arg(CPUState *cs, int argno) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; @@ -23,7 +23,7 @@ uint64_t common_semi_arg(CPUState *cs, int argno) } } -void common_semi_set_ret(CPUState *cs, uint64_t ret) +static void arm_common_semi_set_ret(CPUState *cs, uint64_t ret) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; @@ -34,25 +34,36 @@ void common_semi_set_ret(CPUState *cs, uint64_t ret) } } -bool common_semi_sys_exit_is_extended(CPUState *cs) +static bool arm_common_semi_sys_exit_is_extended(CPUState *cs) { return is_a64(cpu_env(cs)); } -bool is_64bit_semihosting(CPUArchState *env) +static bool arm_is_64bit_semihosting(CPUArchState *env) { return is_a64(env); } -uint64_t common_semi_stack_bottom(CPUState *cs) +static uint64_t arm_common_semi_stack_bottom(CPUState *cs) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; return is_a64(env) ? env->xregs[31] : env->regs[13]; } -bool common_semi_has_synccache(CPUArchState *env) +static bool arm_common_semi_has_synccache(CPUArchState *env) { /* Ok for A64, invalid for A32/T32 */ return is_a64(env); } + +static const CPUSemihostingOps arm_semihosting_ops = { + .arg = arm_common_semi_arg, + .set_ret = arm_common_semi_set_ret, + .is_64bit = arm_is_64bit_semihosting, + .sys_exit_is_extended = arm_common_semi_sys_exit_is_extended, + .stack_bottom = arm_common_semi_stack_bottom, + .has_synccache = arm_common_semi_has_synccache, +}; + +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, semihosting, arm_semihosting_ops); diff --git a/target/arm/meson.build b/target/arm/meson.build index 0369f96b4cc..dfcec55bd97 100644 --- a/target/arm/meson.build +++ b/target/arm/meson.build @@ -44,13 +44,10 @@ arm_stubs_ss.add(files( arm_user_ss.add(files( 'el2-stubs.c', 'cpregs-omap-stub.c', + 'common-semi-target.c', )) -arm_user_ss.add(when: 'CONFIG_ARM_COMPATIBLE_SEMIHOSTING', - if_true: files('common-semi-target.c')) -arm_common_system_ss.add(files('cpu.c')) -arm_common_system_ss.add(when: 'CONFIG_ARM_COMPATIBLE_SEMIHOSTING', - if_true: files('common-semi-target.c')) +arm_common_system_ss.add(files('cpu.c', 'common-semi-target.c')) arm_common_system_ss.add(files( 'arch_dump.c', 'arm-powerctl.c', diff --git a/target/i386/arch_dump.c b/target/i386/arch_dump.c index 16e47c4747d..c060b2b4ccb 100644 --- a/target/i386/arch_dump.c +++ b/target/i386/arch_dump.c @@ -16,6 +16,7 @@ #include "system/dump.h" #include "elf.h" #include "system/memory_mapping.h" +#include "qemu/target-info-qom.h" #define ELF_NOTE_SIZE(hdr_size, name_size, desc_size) \ ((DIV_ROUND_UP((hdr_size), 4) \ @@ -394,7 +395,7 @@ int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cs, return cpu_write_qemu_note(f, &cpu->env, s, 0); } -int cpu_get_dump_info(ArchDumpInfo *info, +static int x86_get_dump_info(ArchDumpInfo *info, const GuestPhysBlockList *guest_phys_blocks) { bool lma = false; @@ -429,7 +430,7 @@ int cpu_get_dump_info(ArchDumpInfo *info, return 0; } -ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) +static ssize_t x86_get_note_size(int class, int machine, int nr_cpus) { int name_size = 5; /* "CORE" or "QEMU" */ size_t elf_note_size = 0; @@ -459,3 +460,6 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) return (elf_note_size + qemu_note_size) * nr_cpus; } + +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_dump_info, x86_get_dump_info); +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_note_size, x86_get_note_size); diff --git a/target/i386/cpu-system.c b/target/i386/cpu-system.c index c8bbf0cbafd..d2babd1ba09 100644 --- a/target/i386/cpu-system.c +++ b/target/i386/cpu-system.c @@ -29,6 +29,7 @@ #include "qapi/qapi-commands-machine.h" #include "cpu-internal.h" +#include "qemu/target-info-qom.h" /* Return a QDict containing keys for all properties that can be included * in static expansion of CPU models. All properties set by x86_cpu_load_model() @@ -188,10 +189,10 @@ out: return xc; } -CpuModelExpansionInfo * -qmp_query_cpu_model_expansion(CpuModelExpansionType type, - CpuModelInfo *model, - Error **errp) +static CpuModelExpansionInfo * +x86_query_cpu_model_expansion(CpuModelExpansionType type, + CpuModelInfo *model, + Error **errp) { X86CPU *xc = NULL; Error *err = NULL; @@ -241,6 +242,9 @@ out: return ret; } +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_model_expansion, + x86_query_cpu_model_expansion); + void cpu_clear_apic_feature(CPUX86State *env) { env->features[FEAT_1_EDX] &= ~CPUID_APIC; diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 5805d33ab92..4e31b8a2a60 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -48,6 +48,7 @@ #include "system/address-spaces.h" #include "hw/core/boards.h" #include "hw/i386/sgx-epc.h" +#include "qemu/target-info-qom.h" #endif #include "system/qtest.h" #include "tcg/tcg-cpu.h" @@ -8191,7 +8192,7 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data) QAPI_LIST_PREPEND(*cpu_list, info); } -CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) +static CpuDefinitionInfoList *x86_query_cpu_definitions(Error **errp) { CpuDefinitionInfoList *cpu_list = NULL; GSList *list = get_sorted_cpu_model_list(); @@ -8200,6 +8201,9 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) return cpu_list; } +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_definitions, + x86_query_cpu_definitions); + #endif /* !CONFIG_USER_ONLY */ static uint8_t x86_cpu_get_host_avx10_version(void) diff --git a/target/loongarch/arch_dump.c b/target/loongarch/arch_dump.c index 9d84faef969..af4ab5df5b5 100644 --- a/target/loongarch/arch_dump.c +++ b/target/loongarch/arch_dump.c @@ -22,6 +22,7 @@ #include "elf.h" #include "system/dump.h" #include "internals.h" +#include "qemu/target-info-qom.h" /* struct user_pt_regs from arch/loongarch/include/uapi/asm/ptrace.h */ struct loongarch_user_regs { @@ -142,7 +143,7 @@ int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, return ret; } -int cpu_get_dump_info(ArchDumpInfo *info, +static int loongarch_get_dump_info(ArchDumpInfo *info, const GuestPhysBlockList *guest_phys_blocks) { info->d_machine = EM_LOONGARCH; @@ -152,7 +153,7 @@ int cpu_get_dump_info(ArchDumpInfo *info, return 0; } -ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) +static ssize_t loongarch_get_note_size(int class, int machine, int nr_cpus) { size_t note_size = 0; @@ -162,3 +163,6 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) return note_size * nr_cpus; } + +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_dump_info, loongarch_get_dump_info); +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_note_size, loongarch_get_note_size); diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c index f053f22bb8c..848ad640aee 100644 --- a/target/loongarch/loongarch-qmp-cmds.c +++ b/target/loongarch/loongarch-qmp-cmds.c @@ -14,6 +14,7 @@ #include "qobject/qdict.h" #include "qapi/qobject-input-visitor.h" #include "qom/qom-qobject.h" +#include "qemu/target-info-qom.h" static void loongarch_cpu_add_definition(gpointer data, gpointer user_data) { @@ -28,7 +29,7 @@ static void loongarch_cpu_add_definition(gpointer data, gpointer user_data) QAPI_LIST_PREPEND(*cpu_list, info); } -CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) +static CpuDefinitionInfoList *loongarch_query_cpu_definitions(Error **errp) { CpuDefinitionInfoList *cpu_list = NULL; GSList *list; @@ -45,9 +46,10 @@ static const char *cpu_model_advertised_features[] = { "ptw", NULL }; -CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, - CpuModelInfo *model, - Error **errp) +static CpuModelExpansionInfo * +loongarch_query_cpu_model_expansion(CpuModelExpansionType type, + CpuModelInfo *model, + Error **errp) { Visitor *visitor; CpuModelExpansionInfo *expansion_info; @@ -133,3 +135,8 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, return expansion_info; } + +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_definitions, + loongarch_query_cpu_definitions); +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_model_expansion, + loongarch_query_cpu_model_expansion); diff --git a/target/mips/system/mips-qmp-cmds.c b/target/mips/system/mips-qmp-cmds.c index b6a2874f2dd..ff78487423b 100644 --- a/target/mips/system/mips-qmp-cmds.c +++ b/target/mips/system/mips-qmp-cmds.c @@ -11,15 +11,7 @@ #include "qapi/error.h" #include "qapi/qapi-commands-machine.h" #include "cpu.h" - -CpuModelExpansionInfo * -qmp_query_cpu_model_expansion(CpuModelExpansionType type, - CpuModelInfo *model, - Error **errp) -{ - error_setg(errp, "CPU model expansion is not supported on this target"); - return NULL; -} +#include "qemu/target-info-qom.h" static void mips_cpu_add_definition(gpointer data, gpointer user_data) { @@ -36,7 +28,7 @@ static void mips_cpu_add_definition(gpointer data, gpointer user_data) QAPI_LIST_PREPEND(*cpu_list, info); } -CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) +static CpuDefinitionInfoList *mips_query_cpu_definitions(Error **errp) { CpuDefinitionInfoList *cpu_list = NULL; GSList *list; @@ -47,3 +39,6 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) return cpu_list; } + +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_definitions, + mips_query_cpu_definitions); diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c index 80ac6c3e320..07f0c75c45e 100644 --- a/target/ppc/arch_dump.c +++ b/target/ppc/arch_dump.c @@ -17,6 +17,7 @@ #include "elf.h" #include "system/dump.h" #include "system/kvm.h" +#include "qemu/target-info-qom.h" #ifdef TARGET_PPC64 #define ELFCLASS ELFCLASS64 @@ -229,7 +230,7 @@ static const struct NoteFuncDescStruct { typedef struct NoteFuncDescStruct NoteFuncDesc; -int cpu_get_dump_info(ArchDumpInfo *info, +static int ppc_get_dump_info(ArchDumpInfo *info, const struct GuestPhysBlockList *guest_phys_blocks) { PowerPCCPU *cpu; @@ -257,7 +258,7 @@ int cpu_get_dump_info(ArchDumpInfo *info, return 0; } -ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) +static ssize_t ppc_get_note_size(int class, int machine, int nr_cpus) { int name_size = 8; /* "CORE" or "QEMU" rounded */ size_t elf_note_size = 0; @@ -313,3 +314,6 @@ int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs, PowerPCCPU *cpu = POWERPC_CPU(cs); return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, s); } + +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_dump_info, ppc_get_dump_info); +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_note_size, ppc_get_note_size); diff --git a/target/ppc/ppc-qmp-cmds.c b/target/ppc/ppc-qmp-cmds.c index 96228919966..70fca0170b1 100644 --- a/target/ppc/ppc-qmp-cmds.c +++ b/target/ppc/ppc-qmp-cmds.c @@ -29,15 +29,7 @@ #include "qapi/qapi-commands-machine.h" #include "cpu-models.h" #include "cpu-qom.h" - -CpuModelExpansionInfo * -qmp_query_cpu_model_expansion(CpuModelExpansionType type, - CpuModelInfo *model, - Error **errp) -{ - error_setg(errp, "CPU model expansion is not supported on this target"); - return NULL; -} +#include "qemu/target-info-qom.h" static void ppc_cpu_defs_entry(gpointer data, gpointer user_data) { @@ -53,7 +45,7 @@ static void ppc_cpu_defs_entry(gpointer data, gpointer user_data) QAPI_LIST_PREPEND(*first, info); } -CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) +static CpuDefinitionInfoList *ppc_query_cpu_definitions(Error **errp) { CpuDefinitionInfoList *cpu_list = NULL; GSList *list; @@ -82,3 +74,6 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) return cpu_list; } + +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_definitions, + ppc_query_cpu_definitions); diff --git a/target/riscv/arch_dump.c b/target/riscv/arch_dump.c index 12b68799070..7e4b584faa0 100644 --- a/target/riscv/arch_dump.c +++ b/target/riscv/arch_dump.c @@ -20,6 +20,7 @@ #include "cpu.h" #include "elf.h" #include "system/dump.h" +#include "qemu/target-info-qom.h" /* struct user_regs_struct from arch/riscv/include/uapi/asm/ptrace.h */ struct riscv64_user_regs { @@ -161,7 +162,7 @@ int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs, return ret; } -int cpu_get_dump_info(ArchDumpInfo *info, +static int riscv_get_dump_info(ArchDumpInfo *info, const GuestPhysBlockList *guest_phys_blocks) { RISCVCPU *cpu; @@ -187,7 +188,7 @@ int cpu_get_dump_info(ArchDumpInfo *info, return 0; } -ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) +static ssize_t riscv_get_note_size(int class, int machine, int nr_cpus) { size_t note_size; @@ -199,3 +200,6 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) return note_size * nr_cpus; } + +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_dump_info, riscv_get_dump_info); +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_note_size, riscv_get_note_size); diff --git a/target/riscv/common-semi-target.c b/target/riscv/common-semi-target.c index aeaeb88d536..aed9dfc5b68 100644 --- a/target/riscv/common-semi-target.c +++ b/target/riscv/common-semi-target.c @@ -12,38 +12,49 @@ #include "cpu.h" #include "semihosting/common-semi.h" -uint64_t common_semi_arg(CPUState *cs, int argno) +static uint64_t riscv_common_semi_arg(CPUState *cs, int argno) { RISCVCPU *cpu = RISCV_CPU(cs); CPURISCVState *env = &cpu->env; return env->gpr[xA0 + argno]; } -void common_semi_set_ret(CPUState *cs, uint64_t ret) +static void riscv_common_semi_set_ret(CPUState *cs, uint64_t ret) { RISCVCPU *cpu = RISCV_CPU(cs); CPURISCVState *env = &cpu->env; env->gpr[xA0] = ret; } -bool is_64bit_semihosting(CPUArchState *env) +static bool riscv_is_64bit_semihosting(CPUArchState *env) { return riscv_cpu_mxl(env) != MXL_RV32; } -bool common_semi_sys_exit_is_extended(CPUState *cs) +static bool riscv_common_semi_sys_exit_is_extended(CPUState *cs) { - return is_64bit_semihosting(cpu_env(cs)); + return riscv_is_64bit_semihosting(cpu_env(cs)); } -uint64_t common_semi_stack_bottom(CPUState *cs) +static uint64_t riscv_common_semi_stack_bottom(CPUState *cs) { RISCVCPU *cpu = RISCV_CPU(cs); CPURISCVState *env = &cpu->env; return env->gpr[xSP]; } -bool common_semi_has_synccache(CPUArchState *env) +static bool riscv_common_semi_has_synccache(CPUArchState *env) { return true; } + +static const CPUSemihostingOps riscv_semihosting_ops = { + .arg = riscv_common_semi_arg, + .set_ret = riscv_common_semi_set_ret, + .is_64bit = riscv_is_64bit_semihosting, + .sys_exit_is_extended = riscv_common_semi_sys_exit_is_extended, + .stack_bottom = riscv_common_semi_stack_bottom, + .has_synccache = riscv_common_semi_has_synccache, +}; + +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, semihosting, riscv_semihosting_ops); diff --git a/target/riscv/meson.build b/target/riscv/meson.build index 42d0f6d538a..5adb6d1c9e7 100644 --- a/target/riscv/meson.build +++ b/target/riscv/meson.build @@ -11,12 +11,10 @@ gen = [ riscv_ss = ss.source_set() riscv_ss.add(gen) -riscv_ss.add(when: 'CONFIG_ARM_COMPATIBLE_SEMIHOSTING', - if_true: files('common-semi-target.c')) - riscv_ss.add(files( 'cpu.c', 'gdbstub.c', + 'common-semi-target.c', )) riscv_system_ss = ss.source_set() diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c index 2647deef916..248e6a0eaf0 100644 --- a/target/riscv/riscv-qmp-cmds.c +++ b/target/riscv/riscv-qmp-cmds.c @@ -36,6 +36,7 @@ #include "cpu-qom.h" #include "cpu.h" #include "target/riscv/tcg/csr.h" +#include "qemu/target-info-qom.h" static void riscv_cpu_add_definition(gpointer data, gpointer user_data) { @@ -54,7 +55,7 @@ static void riscv_cpu_add_definition(gpointer data, gpointer user_data) QAPI_LIST_PREPEND(*cpu_list, info); } -CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) +static CpuDefinitionInfoList *riscv_query_cpu_definitions(Error **errp) { CpuDefinitionInfoList *cpu_list = NULL; GSList *list = object_class_get_list(TYPE_RISCV_CPU, false); @@ -154,9 +155,10 @@ err: visit_free(visitor); } -CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, - CpuModelInfo *model, - Error **errp) +static CpuModelExpansionInfo * +riscv_query_cpu_model_expansion(CpuModelExpansionType type, + CpuModelInfo *model, + Error **errp) { CpuModelExpansionInfo *expansion_info; QDict *qdict_out; @@ -225,3 +227,8 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, return expansion_info; } + +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_definitions, + riscv_query_cpu_definitions); +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_model_expansion, + riscv_query_cpu_model_expansion); diff --git a/target/s390x/arch_dump.c b/target/s390x/arch_dump.c index 2c26e992959..c0334baa72f 100644 --- a/target/s390x/arch_dump.c +++ b/target/s390x/arch_dump.c @@ -18,6 +18,7 @@ #include "elf.h" #include "system/dump.h" #include "kvm/kvm_s390x.h" +#include "qemu/target-info-qom.h" #include "target/s390x/kvm/pv.h" struct S390xUserRegsStruct { @@ -449,7 +450,7 @@ static void arch_cleanup(DumpState *s) } } -int cpu_get_dump_info(ArchDumpInfo *info, +static int s390_get_dump_info(ArchDumpInfo *info, const struct GuestPhysBlockList *guest_phys_blocks) { info->d_machine = EM_S390; @@ -469,7 +470,7 @@ int cpu_get_dump_info(ArchDumpInfo *info, return 0; } -ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) +static ssize_t s390_get_note_size(int class, int machine, int nr_cpus) { int name_size = 8; /* "LINUX" or "CORE" + pad */ size_t elf_note_size = 0; @@ -495,3 +496,6 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) return (elf_note_size) * nr_cpus; } + +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_dump_info, s390_get_dump_info); +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_note_size, s390_get_note_size); diff --git a/target/s390x/cpu_models_system.c b/target/s390x/cpu_models_system.c index 5b846048675..5470bf55e20 100644 --- a/target/s390x/cpu_models_system.c +++ b/target/s390x/cpu_models_system.c @@ -20,6 +20,7 @@ #include "qapi/qobject-input-visitor.h" #include "qobject/qdict.h" #include "qapi/qapi-commands-machine.h" +#include "qemu/target-info-qom.h" static void list_add_feat(const char *name, void *opaque); @@ -82,7 +83,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque) QAPI_LIST_PREPEND(*cpu_list, info); } -CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) +static CpuDefinitionInfoList *s390_query_cpu_definitions(Error **errp) { struct CpuDefinitionInfoListData list_data = { .list = NULL, @@ -208,9 +209,10 @@ static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model, } } -CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, - CpuModelInfo *model, - Error **errp) +static CpuModelExpansionInfo * +s390_query_cpu_model_expansion(CpuModelExpansionType type, + CpuModelInfo *model, + Error **errp) { Error *err = NULL; CpuModelExpansionInfo *expansion_info = NULL; @@ -434,3 +436,8 @@ void apply_cpu_model(const S390CPUModel *model, Error **errp) applied_model = *model; } } + +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_definitions, + s390_query_cpu_definitions); +TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_model_expansion, + s390_query_cpu_model_expansion); -- 2.52.0.windows.1