From: "Daniel P. Berrange" <berrange@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 12/19] Add a query-cputypes command to QMP
Date: Mon, 7 Jun 2010 15:42:25 +0100 [thread overview]
Message-ID: <1275921752-29420-13-git-send-email-berrange@redhat.com> (raw)
In-Reply-To: <1275921752-29420-1-git-send-email-berrange@redhat.com>
This adds a new QMP command called 'query-cputypes' to allow
for discovery of CPU types known to the QEMU binary. This is
intended to relpace the need to parse '-cpu ?', '-cpu ?model'
and '-cpu ?dump'
Most targets have a simple structure listing just the CPU
model names (and optionally a 'description'), with room for
future expansion of extra attributes against each model
{
"cputypes": {
"models": [
{
"name": "arm926"
},
{
"name": "arm946"
},
{
"name": "arm1026"
},
....
]
}
}
The sparc and x86 targets have extra architecture specific
metatadata. These are in keys 'x86info' and 'sparcinfo'
against each CPU model dict. These keys are repeated at the
top level to give data about all allowed feature names
A trimmed example:
{
"cputypes": {
"models": [
{
"name": "n270",
"description": "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
"x86info": {
"xlevel": 2147483658,
"family": 6,
"vendor": "",
"level": 5,
"model": 28,
"stepping": 2,
"features": {
"ext_edx": [
"lahf_lm"
],
"edx": [
"pbe",
"tm",
"ht",
"ss",
"sse2",
...
]
}
}
}
],
"x86info": {
"features": {
"ext_edx": [
21,
20,
"nodeid_msr",
"cvt16",
17,
"fma4",
15,
14,
"wdt",
....
]
}
}
}
}
No mapping to the legacy readline monitor is provided
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
cpus.c | 78 +++++++++++++++++++++++++++++++++++++++++
cpus.h | 1 +
monitor.c | 9 +++++
target-arm/cpu.h | 7 ++++
target-arm/helper.c | 21 +++++++++++
target-cris/cpu.h | 7 ++++
target-cris/translate.c | 22 ++++++++++++
target-i386/cpu.h | 7 ++++
target-i386/cpuid.c | 79 ++++++++++++++++++++++++++++++++++++++++++
target-m68k/cpu.h | 9 +++++
target-m68k/helper.c | 23 ++++++++++++
target-mips/cpu.h | 7 ++++
target-mips/translate.c | 4 ++
target-mips/translate_init.c | 19 ++++++++++
target-ppc/cpu.h | 7 ++++
target-ppc/translate.c | 4 ++
target-ppc/translate_init.c | 17 +++++++++
target-sh4/cpu.h | 8 ++++
target-sh4/translate.c | 23 ++++++++++++
target-sparc/cpu.h | 9 +++++
target-sparc/helper.c | 60 ++++++++++++++++++++++++++++++++
21 files changed, 421 insertions(+), 0 deletions(-)
diff --git a/cpus.c b/cpus.c
index 8341f6c..0943f36 100644
--- a/cpus.c
+++ b/cpus.c
@@ -30,6 +30,7 @@
#include "gdbstub.h"
#include "dma.h"
#include "kvm.h"
+#include "qjson.h"
#include "cpus.h"
@@ -862,3 +863,80 @@ void list_cpus(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
cpu_list(f, cpu_fprintf); /* deprecated */
#endif
}
+
+
+/**
+ * do_info_cpu_types()
+ *
+ * Return information about the CPU types known to this target
+ *
+ * The returned data is a QDict containing one mandatory key:
+ *
+ * - models: a QList of CPU models
+ *
+ * Each CPU model is a QDict containing the following keys
+ *
+ * - name: a short name for the CPU
+ * - description: a long verbose name for the CPU (optional)
+ *
+ * {
+ * "models": [
+ * {
+ * "name": "arm926"
+ * },
+ * {
+ * "name": "arm946"
+ * },
+ * {
+ * "name": "arm1026"
+ * },
+ * ....
+ * ]
+ * }
+ *
+ * Each CPU model can optionally contain architecture
+ * specific data. By convention this is provided in
+ * a key '${ARCH}info', eg i386 and x86_64 targets
+ * provide info about the CPU feature flags, and other
+ * attributes. A single CPU model entry for x86 will
+ * look like
+ *
+ * {
+ * "name": "n270",
+ * "description": "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
+ * "x86info": {
+ * "xlevel": 2147483658,
+ * "family": 6,
+ * "vendor": "",
+ * "level": 5,
+ * "model": 28,
+ * "stepping": 2,
+ * "features": {
+ * "ext_edx": [
+ * "lahf_lm"
+ * ],
+ * "edx": [
+ * "pbe",
+ * "tm",
+ * "ht",
+ * "ss",
+ * "sse2",
+ * ...
+ * ]
+ * }
+ * }
+ * }
+ *
+ * The architecture specific key can also be repeated at
+ * the top level QDict. For example to list the complete
+ * set of allowed features
+ */
+
+void do_info_cpu_types(Monitor *mon, QObject **data)
+{
+#if defined(arch_info_cpu_types)
+ arch_info_cpu_types(data);
+#else
+ *data = qobject_from_jsonf("{ 'models': [] }");
+#endif
+}
diff --git a/cpus.h b/cpus.h
index 774150a..5137866 100644
--- a/cpus.h
+++ b/cpus.h
@@ -18,5 +18,6 @@ void set_numa_modes(void);
void set_cpu_log(const char *optarg);
void list_cpus(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
const char *optarg);
+void do_info_cpu_types(Monitor *mon, QObject **data);
#endif
diff --git a/monitor.c b/monitor.c
index 13f70a0..2c4fb3f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -46,6 +46,7 @@
#include "migration.h"
#include "kvm.h"
#include "acl.h"
+#include "cpus.h"
#include "qint.h"
#include "qfloat.h"
#include "qlist.h"
@@ -2466,6 +2467,14 @@ static const mon_cmd_t info_cmds[] = {
.mhandler.info_new = do_info_devices,
},
{
+ .name = "cputypes",
+ .args_type = "",
+ .params = "",
+ .help = "show the registered CPU models",
+ .user_print = monitor_user_noop,
+ .mhandler.info_new = do_info_cpu_types,
+ },
+ {
.name = "commands",
.args_type = "",
.params = "",
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index f3d138d..3f884b7 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -28,6 +28,9 @@
#include "cpu-defs.h"
#include "softfloat.h"
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
#define TARGET_HAS_ICE 1
@@ -354,6 +357,10 @@ static inline int arm_feature(CPUARMState *env, int feature)
}
void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+#ifdef CONFIG_SOFTMMU
+void arm_info_cpu_types(QObject **data);
+#define arch_info_cpu_types arm_info_cpu_types
+#endif
/* Interface between CPU and Interrupt controller. */
void armv7m_nvic_set_pending(void *opaque, int irq);
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 63e5dc7..bba1530 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -8,6 +8,10 @@
#include "helpers.h"
#include "qemu-common.h"
#include "host-utils.h"
+#ifdef CONFIG_SOFTMMU
+#include "qjson.h"
+#include "qlist.h"
+#endif
#if !defined(CONFIG_USER_ONLY)
#include "hw/loader.h"
#endif
@@ -358,6 +362,23 @@ void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
}
}
+#ifdef CONFIG_SOFTMMU
+void arch_info_cpu_types(QObject **data)
+{
+ QList *models = qlist_new();
+ int i;
+
+ for (i = 0; arm_cpu_names[i].name; i++) {
+ QObject *model = qobject_from_jsonf("{ 'name': %s }",
+ arm_cpu_names[i].name);
+
+ qlist_append_obj(models, model);
+ }
+
+ *data = qobject_from_jsonf("{ 'models': %p }", models);
+}
+#endif
+
/* return 0 if not found */
static uint32_t cpu_arm_find_by_name(const char *name)
{
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index 063a240..b30c10e 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -25,6 +25,9 @@
#define CPUState struct CPUCRISState
#include "cpu-defs.h"
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
#define TARGET_HAS_ICE 1
@@ -267,5 +270,9 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
#define cpu_list cris_cpu_list
void cris_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+#ifdef CONFIG_SOFTMMU
+void cris_info_cpu_types(QObject **data);
+#define arch_info_cpu_types cris_info_cpu_types
+#endif
#endif
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 6c1d9e0..0c326af 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -37,6 +37,10 @@
#include "mmu.h"
#include "crisv32-decode.h"
#include "qemu-common.h"
+#ifdef CONFIG_SOFTMMU
+#include "qlist.h"
+#include "qjson.h"
+#endif
#define GEN_HELPER 1
#include "helper.h"
@@ -3468,6 +3472,24 @@ void cris_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
}
}
+#ifdef CONFIG_SOFTMMU
+void arch_info_cpu_types(QObject **data)
+{
+ QList *models = qlist_new();
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cris_cores) ; i++) {
+ QObject *model = qobject_from_jsonf("{ 'name': %s }",
+ cris_cores[i].name);
+
+ qlist_append_obj(models, model);
+ }
+
+ *data = qobject_from_jsonf("{ 'models': %p }", models);
+}
+#endif
+
+
static uint32_t vr_by_name(const char *name)
{
unsigned int i;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 548ab80..1fa96b8 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -20,6 +20,9 @@
#define CPU_I386_H
#include "config.h"
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
#ifdef TARGET_X86_64
#define TARGET_LONG_BITS 64
@@ -725,6 +728,10 @@ int cpu_x86_exec(CPUX86State *s);
void cpu_x86_close(CPUX86State *s);
void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
const char *optarg);
+#ifdef CONFIG_SOFTMMU
+void x86_info_cpu_types(QObject **data);
+#define arch_info_cpu_types x86_info_cpu_types
+#endif
void x86_cpudef_setup(void);
int cpu_get_pic_interrupt(CPUX86State *s);
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 7a11215..278f650 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -26,6 +26,12 @@
#include "qemu-option.h"
#include "qemu-config.h"
+#ifdef CONFIG_SOFTMMU
+#include "qstring.h"
+#include "qjson.h"
+#include "qint.h"
+#include "qdict.h"
+#endif
/* feature flags taken from "Intel Processor Identification and the CPUID
* Instruction" and AMD's "CPUID Specification". In cases of disagreement
@@ -784,6 +790,79 @@ void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
}
}
+
+#ifdef CONFIG_SOFTMMU
+static void qemu_caps_cpu_feature(QDict *features, const char *type,
+ uint32_t fbits,
+ const char **featureset)
+{
+ QList *set = qlist_new();
+ const char **p = &featureset[31];
+ char bit;
+
+ for (bit = 31; fbits ; --p, fbits &= ~(1 << bit), --bit) {
+ if (fbits & 1 << bit) {
+ if (*p) {
+ qlist_append_obj(set, QOBJECT(qstring_from_str(*p)));
+ } else {
+ qlist_append_obj(set, QOBJECT(qint_from_int(bit)));
+ }
+ }
+ }
+ qdict_put_obj(features, type, QOBJECT(set));
+}
+
+void arch_info_cpu_types(QObject **data)
+{
+ QList *models = qlist_new();
+ QDict *allfeatures = qdict_new();
+ x86_def_t *def;
+ char buf[256];
+
+ for (def = x86_defs; def; def = def->next) {
+ QObject *model;
+ QObject *x86info;
+ QDict *features = qdict_new();
+
+ memcpy(buf, &def->vendor1, sizeof (def->vendor1));
+ memcpy(buf + 4, &def->vendor2, sizeof (def->vendor2));
+ memcpy(buf + 8, &def->vendor3, sizeof (def->vendor3));
+ buf[12] = '\0';
+
+ qemu_caps_cpu_feature(features, "edx", def->features, feature_name);
+ qemu_caps_cpu_feature(features, "ecx", def->ext_features, ext_feature_name);
+ qemu_caps_cpu_feature(features, "ext_ecx", def->ext2_features, ext2_feature_name);
+ qemu_caps_cpu_feature(features, "ext_edx", def->ext3_features, ext3_feature_name);
+
+ x86info = qobject_from_jsonf("{ 'family': %d, 'model': %d, 'stepping': %d,"
+ " 'level': %d, 'xlevel': %" PRId64 ", 'vendor': %s, 'features': %p }",
+ def->family, def->model, def->stepping,
+ def->level, (int64_t)def->xlevel, buf, features);
+
+ model = qobject_from_jsonf("{ 'name': %s, 'description': %s, 'x86info': %p }",
+ def->name, def->model_id, x86info);
+
+ qlist_append_obj(models, model);
+ }
+ if (kvm_enabled()) {
+ /* XXX: fill in model + x86info fields based on host */
+ QObject *model = qobject_from_jsonf("{ 'name': %s }",
+ "host");
+
+ qlist_append_obj(models, model);
+ }
+
+ qemu_caps_cpu_feature(allfeatures, "edx", ~0, feature_name);
+ qemu_caps_cpu_feature(allfeatures, "ecx", ~0, ext_feature_name);
+ qemu_caps_cpu_feature(allfeatures, "ext_ecx", ~0, ext2_feature_name);
+ qemu_caps_cpu_feature(allfeatures, "ext_edx", ~0, ext3_feature_name);
+
+ *data = qobject_from_jsonf("{ 'models': %p, 'x86info': { 'features': %p } }",
+ models, allfeatures);
+}
+#endif
+
+
int cpu_x86_register (CPUX86State *env, const char *cpu_model)
{
x86_def_t def1, *def = &def1;
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index b2f37ec..ac5f6bd 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -28,6 +28,10 @@
#include "softfloat.h"
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
+
#define MAX_QREGS 32
#define TARGET_HAS_ICE 1
@@ -200,6 +204,11 @@ static inline int m68k_feature(CPUM68KState *env, int feature)
void m68k_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+#ifdef CONFIG_SOFTMMU
+void m68k_info_cpu_types(QObject **data);
+#define arch_info_cpu_types m68k_info_cpu_types
+#endif
+
void register_m68k_insns (CPUM68KState *env);
#ifdef CONFIG_USER_ONLY
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index b4ebb14..9de6722 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -26,6 +26,10 @@
#include "exec-all.h"
#include "qemu-common.h"
#include "gdbstub.h"
+#ifdef CONFIG_SOFTMMU
+#include "qlist.h"
+#include "qjson.h"
+#endif
#include "helpers.h"
@@ -62,6 +66,25 @@ void m68k_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
}
}
+
+#ifdef CONFIG_SOFTMMU
+void arch_info_cpu_types(QObject **data)
+{
+ QList *models = qlist_new();
+ int i;
+
+ for (i = 0; m68k_cpu_defs[i].name; i++) {
+ QObject *model = qobject_from_jsonf("{ 'name': %s }",
+ m68k_cpu_defs[i].name);
+
+ qlist_append_obj(models, model);
+ }
+
+ *data = qobject_from_jsonf("{ 'models': %p }", models);
+}
+#endif
+
+
static int fpu_gdb_get_reg(CPUState *env, uint8_t *mem_buf, int n)
{
if (n < 8) {
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 7285636..02bcadb 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -11,6 +11,9 @@
#include "mips-defs.h"
#include "cpu-defs.h"
#include "softfloat.h"
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
// uint_fast8_t and uint_fast16_t not in <sys/int_types.h>
// XXX: move that elsewhere
@@ -496,6 +499,10 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
#endif
void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+#ifdef CONFIG_SOFTMMU
+void mips_info_cpu_types(QObject **data);
+#define arch_info_cpu_types mips_info_cpu_types
+#endif
#define cpu_init cpu_mips_init
#define cpu_exec cpu_mips_exec
diff --git a/target-mips/translate.c b/target-mips/translate.c
index c95ecb1..0d9fd80 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -35,6 +35,10 @@
#include "helper.h"
#define GEN_HELPER 1
#include "helper.h"
+#ifdef CONFIG_SOFTMMU
+#include "qlist.h"
+#include "qjson.h"
+#endif
//#define MIPS_DEBUG_DISAS
//#define MIPS_DEBUG_SIGN_EXTENSIONS
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index b79ed56..72ee283 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -479,6 +479,25 @@ void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
}
}
+
+#ifdef CONFIG_SOFTMMU
+void arch_info_cpu_types(QObject **data)
+{
+ QList *models = qlist_new();
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mips_defs); i++) {
+ QObject *model = qobject_from_jsonf("{ 'name': %s }",
+ mips_defs[i].name);
+
+ qlist_append_obj(models, model);
+ }
+
+ *data = qobject_from_jsonf("{ 'models': %p }", models);
+}
+#endif
+
+
#ifndef CONFIG_USER_ONLY
static void no_mmu_init (CPUMIPSState *env, const mips_def_t *def)
{
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 2ad4486..69e0686 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -21,6 +21,9 @@
#include "config.h"
#include <inttypes.h>
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
//#define PPC_EMULATE_32BITS_HYPV
@@ -758,6 +761,10 @@ void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value);
void ppc_store_msr (CPUPPCState *env, target_ulong value);
void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+#ifdef CONFIG_SOFTMMU
+void ppc_info_cpu_types(QObject **data);
+#define arch_info_cpu_types ppc_info_cpu_types
+#endif
const ppc_def_t *cpu_ppc_find_by_name (const char *name);
int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def);
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 66e1c0d..8e6c9e3 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -28,6 +28,10 @@
#include "tcg-op.h"
#include "qemu-common.h"
#include "host-utils.h"
+#ifdef CONFIG_SOFTMMU
+#include "qlist.h"
+#include "qjson.h"
+#endif
#include "helper.h"
#define GEN_HELPER 1
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index e8eadf4..4b4097a 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -9764,3 +9764,20 @@ void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
ppc_defs[i].name, ppc_defs[i].pvr);
}
}
+
+#ifdef CONFIG_SOFTMMU
+void arch_info_cpu_types(QObject **data)
+{
+ QList *models = qlist_new();
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ppc_defs); i++) {
+ QObject *model = qobject_from_jsonf("{ 'name': %s }",
+ ppc_defs[i].name);
+
+ qlist_append_obj(models, model);
+ }
+
+ *data = qobject_from_jsonf("{ 'models': %p }", models);
+}
+#endif
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index f8b1680..a0a6ed5 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -20,6 +20,9 @@
#define _CPU_SH4_H
#include "config.h"
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
#define TARGET_LONG_BITS 32
#define TARGET_HAS_ICE 1
@@ -169,6 +172,11 @@ int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
void do_interrupt(CPUSH4State * env);
void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+#ifdef CONFIG_SOFTMMU
+void sh4_info_cpu_types(QObject **data);
+#define arch_info_cpu_types sh4_info_cpu_types
+#endif
+
#if !defined(CONFIG_USER_ONLY)
void cpu_sh4_invalidate_tlb(CPUSH4State *s);
void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index d0d6c00..7d94ad2 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -31,6 +31,10 @@
#include "disas.h"
#include "tcg-op.h"
#include "qemu-common.h"
+#ifdef CONFIG_SOFTMMU
+#include "qlist.h"
+#include "qjson.h"
+#endif
#include "helper.h"
#define GEN_HELPER 1
@@ -265,6 +269,25 @@ void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
(*cpu_fprintf)(f, "%s\n", sh4_defs[i].name);
}
+
+#ifdef CONFIG_SOFTMMU
+void arch_info_cpu_types(QObject **data)
+{
+ QList *models = qlist_new();
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sh4_defs); i++) {
+ QObject *model = qobject_from_jsonf("{ 'name': %s }",
+ sh4_defs[i].name);
+
+ qlist_append_obj(models, model);
+ }
+
+ *data = qobject_from_jsonf("{ 'models': %p }", models);
+}
+#endif
+
+
static void cpu_sh4_register(CPUSH4State *env, const sh4_def_t *def)
{
env->pvr = def->pvr;
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 8f0484b..7b433ed 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -27,6 +27,10 @@
#include "softfloat.h"
+#ifdef CONFIG_SOFTMMU
+#include "qobject.h"
+#endif
+
#define TARGET_HAS_ICE 1
#if !defined(TARGET_SPARC64)
@@ -444,6 +448,11 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model);
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
...));
+#ifdef CONFIG_SOFTMMU
+void sparc_info_cpu_types(QObject **data);
+#define arch_info_cpu_types sparc_info_cpu_types
+#endif
+
void cpu_lock(void);
void cpu_unlock(void);
int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw,
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index aa1fd63..15b4cc2 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -26,6 +26,11 @@
#include "cpu.h"
#include "exec-all.h"
#include "qemu-common.h"
+#ifdef CONFIG_SOFTMMU
+#include "qlist.h"
+#include "qdict.h"
+#include "qjson.h"
+#endif
//#define DEBUG_MMU
//#define DEBUG_FEATURES
@@ -1479,6 +1484,61 @@ void sparc_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
"fpu_version mmu_version nwindows\n");
}
+
+#ifdef CONFIG_SOFTMMU
+static void cpu_type_feature_info(QDict *info,
+ const char *name,
+ uint32_t bits)
+{
+ QList *features = qlist_new();
+ unsigned int i;
+
+ qdict_put_obj(info, name, QOBJECT(features));
+
+ for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
+ if (feature_name[i] && (bits & (1 << i))) {
+ qlist_append_obj(features, QOBJECT(qstring_from_str(feature_name[i])));
+ }
+ }
+}
+
+void arch_info_cpu_types(QObject **data)
+{
+ QList *models = qlist_new();
+ QDict *allsparcinfo = qdict_new();
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
+ QObject *model;
+ QDict *sparcinfo = qdict_new();
+
+ cpu_type_feature_info(sparcinfo, "features",
+ sparc_defs[i].features);
+
+ model = qobject_from_jsonf("{ 'name': %s, 'sparcinfo': %p, "
+ " 'iu_version': %" PRId64 ", "
+ " 'fpu_version': %" PRId64 ", "
+ " 'mmu_version': %" PRId64 ", "
+ " 'nwindows': %d }",
+ sparc_defs[i].name, sparcinfo,
+ (uint64_t)sparc_defs[i].iu_version,
+ (uint64_t)sparc_defs[i].fpu_version,
+ (uint64_t)sparc_defs[i].mmu_version,
+ sparc_defs[i].nwindows);
+
+ qlist_append_obj(models, model);
+ }
+
+ cpu_type_feature_info(allsparcinfo, "features",
+ ~0);
+ cpu_type_feature_info(allsparcinfo, "deffeatures",
+ CPU_DEFAULT_FEATURES);
+
+ *data = qobject_from_jsonf("{ 'models': %p, 'sparcinfo': %p }",
+ models, allsparcinfo);
+}
+#endif
+
static void cpu_print_cc(FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
uint32_t cc)
--
1.6.6.1
next prev parent reply other threads:[~2010-06-07 14:44 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-07 14:42 [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Daniel P. Berrange
2010-06-07 14:42 ` [Qemu-devel] [PATCH 01/19] Add support for JSON pretty printing Daniel P. Berrange
2010-06-09 19:51 ` Luiz Capitulino
2010-06-07 14:42 ` [Qemu-devel] [PATCH 02/19] Add support for compile time assertions Daniel P. Berrange
2010-06-07 15:35 ` [Qemu-devel] " Paolo Bonzini
2010-06-07 14:42 ` [Qemu-devel] [PATCH 03/19] Add enum handlers for easy & efficient string <-> int conversion Daniel P. Berrange
2010-06-09 19:52 ` Luiz Capitulino
2010-06-26 6:52 ` Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 04/19] Add support for a option parameter as an enum Daniel P. Berrange
2010-06-26 6:59 ` Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 05/19] Ensure that QEMU exits if drive_add parsing fails Daniel P. Berrange
2010-06-26 7:04 ` Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 06/19] Convert drive options to use enumeration data type Daniel P. Berrange
2010-06-09 19:52 ` Luiz Capitulino
2010-06-26 7:07 ` Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 07/19] Convert netdev client types to use an enumeration Daniel P. Berrange
2010-06-07 15:09 ` Anthony Liguori
2010-06-07 15:13 ` Daniel P. Berrange
2010-06-07 14:42 ` [Qemu-devel] [PATCH 08/19] Convert RTC to use enumerations for configuration parameters Daniel P. Berrange
2010-06-09 19:54 ` Luiz Capitulino
2010-06-07 14:42 ` [Qemu-devel] [PATCH 09/19] Change 'query-version' to output broken down version string Daniel P. Berrange
2010-06-07 15:11 ` Anthony Liguori
2010-06-09 20:04 ` Luiz Capitulino
2010-06-07 14:42 ` [Qemu-devel] [PATCH 10/19] Add a query-machines command to QMP Daniel P. Berrange
2010-06-07 15:13 ` Anthony Liguori
2010-06-07 16:44 ` Daniel P. Berrange
2010-06-07 17:07 ` Anthony Liguori
2010-06-07 17:14 ` Daniel P. Berrange
2010-06-09 20:06 ` Luiz Capitulino
2010-06-07 14:42 ` [Qemu-devel] [PATCH 11/19] Add a query-devices " Daniel P. Berrange
2010-06-07 15:14 ` Anthony Liguori
2010-06-07 16:03 ` Daniel P. Berrange
2010-06-26 7:12 ` Markus Armbruster
2010-06-07 14:42 ` Daniel P. Berrange [this message]
2010-06-26 7:18 ` [Qemu-devel] [PATCH 12/19] Add a query-cputypes " Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 13/19] Add a query-target " Daniel P. Berrange
2010-06-07 15:43 ` [Qemu-devel] " Paolo Bonzini
2010-06-07 14:42 ` [Qemu-devel] [PATCH 14/19] Add a query-argv " Daniel P. Berrange
2010-06-07 15:01 ` Anthony Liguori
2010-06-10 15:34 ` [Qemu-devel] " Paolo Bonzini
2010-06-26 7:30 ` [Qemu-devel] " Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 15/19] Expand query-argv to include help string Daniel P. Berrange
2010-06-07 14:42 ` [Qemu-devel] [PATCH 16/19] Add a query-netdev command to QMP Daniel P. Berrange
2010-06-07 15:15 ` Anthony Liguori
2010-06-26 7:32 ` Markus Armbruster
2010-06-07 19:13 ` Miguel Di Ciurcio Filho
2010-06-08 8:38 ` Daniel P. Berrange
2010-06-07 14:42 ` [Qemu-devel] [PATCH 17/19] Add a query-config " Daniel P. Berrange
2010-06-26 7:34 ` Markus Armbruster
2010-06-07 14:42 ` [Qemu-devel] [PATCH 18/19] Add option to turn on JSON pretty printing in monitor Daniel P. Berrange
2010-06-07 14:42 ` [Qemu-devel] [PATCH 19/19] Add a -capabilities argument to allow easy query for static QEMU info Daniel P. Berrange
2010-06-07 16:04 ` [Qemu-devel] " Paolo Bonzini
2010-06-07 16:09 ` Daniel P. Berrange
2010-06-07 16:04 ` [Qemu-devel] " Anthony Liguori
2010-06-07 14:58 ` [Qemu-devel] [PATCH 00/19] RFC: Reporting QEMU binary capabilities Anthony Liguori
2010-06-07 15:10 ` Daniel P. Berrange
2010-06-07 15:18 ` Anthony Liguori
2010-06-07 16:02 ` [Qemu-devel] " Paolo Bonzini
2010-06-07 16:03 ` Anthony Liguori
2010-06-07 16:07 ` [Qemu-devel] " Anthony Liguori
2010-06-09 20:25 ` Luiz Capitulino
2010-06-26 6:45 ` Markus Armbruster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1275921752-29420-13-git-send-email-berrange@redhat.com \
--to=berrange@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).