From 86f4b6871c598e86f0542ed50d2ee5280fc66590 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 18 Nov 2015 01:52:59 -0700 Subject: cpu: Convert CpuInfo into flat union The CpuInfo struct is used only by the 'query-cpus' output command, so we are free to modify it by adding fields (clients are already supposed to ignore unknown output fields), or by changing optional members to mandatory, while still keeping QMP wire compatibility with older versions of qemu. When qapi type CpuInfo was originally created for 0.14, we had no notion of a flat union, and instead just listed a bunch of optional fields with documentation about the mutually-exclusive choice of which instruction pointer field(s) would be provided for a given architecture. But now that we have flat unions and introspection, it is better to segregate off which fields will be provided according to the actual architecture. With this in place, we no longer need the fields to be optional, because the choice of the new 'arch' discriminator serves that role. This has an additional benefit: the old all-in-one struct was the only place in the code base that had a case-sensitive naming of members 'pc' vs. 'PC'. Separating these spellings into different branches of the flat union will allow us to add restrictions against future case-insensitive collisions, since that is generally a poor interface practice. Signed-off-by: Eric Blake Message-Id: <1447836791-369-25-git-send-email-eblake@redhat.com> [Spelling of CPUInfo{SPARC,PPC,MIPS} fixed] Signed-off-by: Markus Armbruster --- cpus.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'cpus.c') diff --git a/cpus.c b/cpus.c index 43676fa1f3..ea29584397 100644 --- a/cpus.c +++ b/cpus.c @@ -1558,22 +1558,29 @@ CpuInfoList *qmp_query_cpus(Error **errp) info->value->qom_path = object_get_canonical_path(OBJECT(cpu)); info->value->thread_id = cpu->thread_id; #if defined(TARGET_I386) - info->value->has_pc = true; - info->value->pc = env->eip + env->segs[R_CS].base; + info->value->arch = CPU_INFO_ARCH_X86; + info->value->u.x86 = g_new0(CpuInfoX86, 1); + info->value->u.x86->pc = env->eip + env->segs[R_CS].base; #elif defined(TARGET_PPC) - info->value->has_nip = true; - info->value->nip = env->nip; + info->value->arch = CPU_INFO_ARCH_PPC; + info->value->u.ppc = g_new0(CpuInfoPPC, 1); + info->value->u.ppc->nip = env->nip; #elif defined(TARGET_SPARC) - info->value->has_pc = true; - info->value->pc = env->pc; - info->value->has_npc = true; - info->value->npc = env->npc; + info->value->arch = CPU_INFO_ARCH_SPARC; + info->value->u.sparc = g_new0(CpuInfoSPARC, 1); + info->value->u.sparc->pc = env->pc; + info->value->u.sparc->npc = env->npc; #elif defined(TARGET_MIPS) - info->value->has_PC = true; - info->value->PC = env->active_tc.PC; + info->value->arch = CPU_INFO_ARCH_MIPS; + info->value->u.mips = g_new0(CpuInfoMIPS, 1); + info->value->u.mips->PC = env->active_tc.PC; #elif defined(TARGET_TRICORE) - info->value->has_PC = true; - info->value->PC = env->PC; + info->value->arch = CPU_INFO_ARCH_TRICORE; + info->value->u.tricore = g_new0(CpuInfoTricore, 1); + info->value->u.tricore->PC = env->PC; +#else + info->value->arch = CPU_INFO_ARCH_OTHER; + info->value->u.other = g_new0(CpuInfoOther, 1); #endif /* XXX: waiting for the qapi to support GSList */ -- cgit v1.2.3