From: Bill Carson bill4car...@gmail.com
This patch add some A15 codes which enables ARM KVM could run
Guest OS build with Versatile Express Cortex-A15x4 tile.
Signed-off-by: Bill Carson bill4car...@gmail.com
---
Makefile.target |2 +-
hw/a15mpcore.c | 146 ++
hw/vexpress.c | 192 +++
target-arm/cpu.h|1 +
target-arm/helper.c | 31
5 files changed, 371 insertions(+), 1 deletions(-)
create mode 100644 hw/a15mpcore.c
diff --git a/Makefile.target b/Makefile.target
index 2501c63..3899869 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -331,7 +331,7 @@ endif
obj-arm-y = integratorcp.o versatilepb.o arm_pic.o arm_timer.o
obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
obj-arm-y += versatile_pci.o
-obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
+obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
a15mpcore.o
obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
obj-arm-y += pl061.o
obj-arm-y += arm-semi.o
diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
new file mode 100644
index 000..cf7ec38
--- /dev/null
+++ b/hw/a15mpcore.c
@@ -0,0 +1,146 @@
+/*
+ * ARM MPCore internal peripheral emulation (common code).
+ *
+ * Copyright (c) 2006-2007 CodeSourcery.
+ * Written by Paul Brook
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include sysbus.h
+#include qemu-timer.h
+
+/* 64 external IRQ lines. */
+#define GIC_NIRQ 96
+
+
+#define NCPU 4
+
+static inline int
+gic_get_current_cpu(void)
+{
+ return cpu_single_env-cpu_index;
+}
+
+#include arm_gic.c
+
+/* MPCore private memory region. */
+
+typedef struct {
+uint32_t count;
+uint32_t load;
+uint32_t control;
+uint32_t status;
+uint32_t old_status;
+int64_t tick;
+QEMUTimer *timer;
+struct a15mpcore_priv_state *mpcore;
+int id; /* Encodes both timer/watchdog and CPU. */
+} mpcore_timer_state;
+
+typedef struct a15mpcore_priv_state {
+gic_state gic;
+uint32_t scu_control;
+int iomemtype;
+mpcore_timer_state timer[8];
+uint32_t num_cpu;
+} a15mpcore_priv_state;
+
+/* TODO:Per-CPU Timers. */
+
+
+/* Per-CPU private memory mapped IO. */
+
+static uint32_t a15mpcore_priv_read(void *opaque, target_phys_addr_t offset)
+{
+a15mpcore_priv_state *s = (a15mpcore_priv_state *)opaque;
+int id;
+offset = 0xfff;
+ uint32_t value;
+
+/* Interrupt controller. */
+if (offset 0x200) {
+ id = gic_get_current_cpu();
+} else {
+ id = (offset - 0x200) 8;
+if (id = s-num_cpu) {
+ return 0;
+}
+ }
+
+ value = gic_cpu_read(s-gic, id, offset 0xff);
+ return value;
+}
+
+static void a15mpcore_priv_write(void *opaque, target_phys_addr_t offset,
+ uint32_t value)
+{
+a15mpcore_priv_state *s = (a15mpcore_priv_state *)opaque;
+ int id;
+
+offset = 0xfff;
+/* Interrupt controller. */
+if (offset 0x200) {
+ id = gic_get_current_cpu();
+} else {
+id = (offset - 0x200) 8;
+}
+if (id s-num_cpu) {
+gic_cpu_write(s-gic, id, offset 0xff, value);
+ }
+
+return;
+}
+
+static CPUReadMemoryFunc * const a15mpcore_priv_readfn[] = {
+ a15mpcore_priv_read,
+ a15mpcore_priv_read,
+ a15mpcore_priv_read
+};
+
+static CPUWriteMemoryFunc * const a15mpcore_priv_writefn[] = {
+ a15mpcore_priv_write,
+ a15mpcore_priv_write,
+ a15mpcore_priv_write
+};
+
+static void a15mpcore_priv_map(SysBusDevice *dev, target_phys_addr_t base)
+{
+a15mpcore_priv_state *s = FROM_SYSBUSGIC(a15mpcore_priv_state, dev);
+cpu_register_physical_memory(base + 0x2000, 0x1000, s-iomemtype);/* cpu
interface */
+cpu_register_physical_memory(base + 0x1000, 0x1000, s-gic.iomemtype);/*
distributor */
+}
+
+static int a15mpcore_priv_init(SysBusDevice *dev)
+{
+a15mpcore_priv_state *s = FROM_SYSBUSGIC(a15mpcore_priv_state, dev);
+
+gic_init(s-gic, s-num_cpu);
+s-iomemtype = cpu_register_io_memory(a15mpcore_priv_readfn,
+ a15mpcore_priv_writefn, s,
+ DEVICE_NATIVE_ENDIAN);
+sysbus_init_mmio_cb(dev, 0x2000, a15mpcore_priv_map);
+return 0;
+}
+
+
+static SysBusDeviceInfo a15mpcore_priv_info = {
+.init = a15mpcore_priv_init,
+.qdev.name = a15mpcore_priv,
+.qdev.size = sizeof(a15mpcore_priv_state),
+.qdev.props = (Property[]) {
+DEFINE_PROP_UINT32(num-cpu, a15mpcore_priv_state, num_cpu, 1),
+DEFINE_PROP_END_OF_LIST(),
+}
+};
+
+static void a15mpcore_register_devices(void)
+{
+sysbus_register_withprop(a15mpcore_priv_info);
+}
+
+device_init(a15mpcore_register_devices)
+
+
+
+
diff --git a/hw/vexpress.c b/hw/vexpress.c
index 9ffd332..168819f 100644
--- a/hw/vexpress.c
+++