Create a CPU subclass, and register classes matching all CPU models
except for "pxa270", which is an alias for "pxa270-a0".
Let arm_cpu_list() enumerate CPU subclasses in alphabetical order,
except for special value "any".
Replace cpu_arm_find_by_name()'s string -> CPUID lookup by storing the
CPUID in the class.
NB: CPUIDs were first introduced by Paul Brook in r1765 (2006).
Signed-off-by: Andreas Färber<address@hidden>
Cc: Anthony Liguori<address@hidden>
Cc: Paul Brook<address@hidden>
Cc: Peter Maydell<address@hidden>
---
Makefile.target | 1 +
target-arm/cpu-qom.h | 64 +++++++++++++++++
target-arm/cpu.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++
target-arm/cpu.h | 1 -
target-arm/helper.c | 108 +++++++++++++---------------
5 files changed, 308 insertions(+), 59 deletions(-)
create mode 100644 target-arm/cpu-qom.h
create mode 100644 target-arm/cpu.c
diff --git a/Makefile.target b/Makefile.target
index cb1532a..c2c4bca 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -87,6 +87,7 @@ endif
libobj-$(TARGET_SPARC64) += vis_helper.o
libobj-$(CONFIG_NEED_MMU) += mmu.o
libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o
+libobj-$(TARGET_ARM) += cpu.o
ifeq ($(TARGET_BASE_ARCH), sparc)
libobj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o
libobj-y += cpu_init.o
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
new file mode 100644
index 0000000..b2917ea
--- /dev/null
+++ b/target-arm/cpu-qom.h
@@ -0,0 +1,64 @@
+/*
+ * QEMU ARM CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ *<http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+#ifndef QEMU_ARM_CPU_QOM_H
+#define QEMU_ARM_CPU_QOM_H
+
+#include "qemu/cpu.h"
+
+#define TYPE_ARM_CPU "arm-cpu"
+
+#define ARM_CPU_CLASS(klass) \
+ OBJECT_CLASS_CHECK(ARMCPUClass, (klass), TYPE_ARM_CPU)
+#define ARM_CPU(obj) \
+ OBJECT_CHECK(ARMCPU, (obj), TYPE_ARM_CPU)
+#define ARM_CPU_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU)
+
+/**
+ * ARMCPUClass:
+ * @parent_reset: The parent class' reset handler.
+ *
+ * An ARM CPU model.
+ */
+typedef struct ARMCPUClass {
+ /*< private>*/
+ CPUClass parent_class;
+ /*< public>*/
+
+ void (*parent_reset)(CPUState *cpu);
+
+ struct {
+ uint32_t c0_cpuid;
+ } cp15;
+} ARMCPUClass;
+
+/**
+ * ARMCPU:
+ *
+ * An ARM CPU core.
+ */
+typedef struct ARMCPU {
+ /*< private>*/
+ CPUState parent_obj;
+ /*< public>*/
+} ARMCPU;
+
+
+#endif
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
new file mode 100644
index 0000000..dabc094
--- /dev/null
+++ b/target-arm/cpu.c
@@ -0,0 +1,193 @@
+/*
+ * QEMU ARM CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ *<http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+
+#include "cpu-qom.h"
+#include "qemu-common.h"
+
+static void arm_cpu_reset(CPUState *c)
+{
+ ARMCPUClass *klass = ARM_CPU_GET_CLASS(c);
+
+ klass->parent_reset(c);
+}
+
+/* CPU models */
+
+typedef struct ARMCPUInfo {
+ const char *name;
+ uint32_t id;
+} ARMCPUInfo;
+
+static const ARMCPUInfo arm_cpus[] = {
+ {
+ .name = "arm926",
+ .id = 0x41069265,
+ },
+ {
+ .name = "arm946",
+ .id = 0x41059461,
+ },
+ {
+ .name = "arm1026",
+ .id = 0x4106a262,
+ },
+ /* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an
+ * older core than plain "arm1136". In particular this does not
+ * have the v6K features.
+ */
+ {
+ .name = "arm1136-r2",
+ .id = 0x4107b362,
+ },
+ {
+ .name = "arm1136",
+ .id = 0x4117b363,
+ },
+ {
+ .name = "arm1176",
+ .id = 0x410fb767,
+ },
+ {
+ .name = "arm11mpcore",
+ .id = 0x410fb022,
+ },
+ {
+ .name = "cortex-m3",
+ .id = 0x410fc231,
+ },
+ {
+ .name = "cortex-a8",
+ .id = 0x410fc080,
+ },
+ {
+ .name = "cortex-a9",
+ .id = 0x410fc090,
+ },
+ {
+ .name = "cortex-a15",
+ .id = 0x412fc0f1,
+ },
+ {
+ .name = "ti925t",
+ .id = 0x54029252,
+ },
+ {
+ .name = "sa1100",
+ .id = 0x4401A11B,
+ },
+ {
+ .name = "sa1110",
+ .id = 0x6901B119,
+ },
+ {
+ .name = "pxa250",
+ .id = 0x69052100,
+ },
+ {
+ .name = "pxa255",
+ .id = 0x69052d00,
+ },
+ {
+ .name = "pxa260",
+ .id = 0x69052903,
+ },
+ {
+ .name = "pxa261",
+ .id = 0x69052d05,
+ },
+ {
+ .name = "pxa262",
+ .id = 0x69052d06,
+ },
+ {
+ .name = "pxa270-a0",
+ .id = 0x69054110,
+ },
+ {
+ .name = "pxa270-a1",
+ .id = 0x69054111,
+ },
+ {
+ .name = "pxa270-b0",
+ .id = 0x69054112,
+ },
+ {
+ .name = "pxa270-b1",
+ .id = 0x69054113,
+ },
+ {
+ .name = "pxa270-c0",
+ .id = 0x69054114,
+ },
+ {
+ .name = "pxa270-c5",
+ .id = 0x69054117,
+ },
+ {
+ .name = "any",
+ .id = 0xffffffff,
+ },
+};
+
+static void arm_cpu_class_init(ObjectClass *klass, void *data)
+{
+ ARMCPUClass *k = ARM_CPU_CLASS(klass);
+ CPUClass *cpu_class = CPU_CLASS(klass);
+ const ARMCPUInfo *info = data;
+
+ k->parent_reset = cpu_class->reset;
+ cpu_class->reset = arm_cpu_reset;
+
+ k->cp15.c0_cpuid = info->id;
+}
+
+static void cpu_register(const ARMCPUInfo *info)
+{
+ TypeInfo type = {
+ .name = info->name,
+ .parent = TYPE_ARM_CPU,
+ .instance_size = sizeof(ARMCPU),
+ .class_size = sizeof(ARMCPUClass),
+ .class_init = arm_cpu_class_init,
+ .class_data = (void *)info,
+ };