Re: [Qemu-devel] [PATCH] Add Qemu A15 minimal support for ARM KVM

2011-10-24 Thread Peter Maydell
On 29 September 2011 08:30,  bill4car...@gmail.com wrote:
 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.

Thanks for sending this; I have somewhat belatedly written
up some comments on it.

I see the a15mpcore.c code is based on a version of mpcore.c
which predates the MemoryRegion API changes -- we'll need to
update it to use MemoryRegions.

There are some relics of 11MPCore peripherals lurking in there
which need to be taken out. (I think we should probably clean
up mpcore.c to separate out A9 from 11MPCore, incidentally.)

The vexpress A9 and A15 init functions can probably share
code although I haven't looked too closely there.

For QEMU TCG we're going to want to model at least some
of the cp15 registers (although probably mostly dummy
implementations).

The A15 generic timer is accessed via cp15 registers rather
than being memory mapped -- we need to decide which side of
the KVM/QEMU boundary the model of that should live. (I'm
guessing the right answer is qemu side which means we'll
need an ABI between KVM and QEMU to pass (some) cp15 accesses
through.)

thanks again
-- PMM



Re: [Qemu-devel] [PATCH] Add Qemu A15 minimal support for ARM KVM

2011-10-24 Thread bill4carson



On 2011年10月24日 22:09, Peter Maydell wrote:

On 29 September 2011 08:30,bill4car...@gmail.com  wrote:

From: Bill Carsonbill4car...@gmail.com

This patch add some A15 codes which enables ARM KVM could run
Guest OS build with Versatile Express Cortex-A15x4 tile.

Thanks for sending this; I have somewhat belatedly written
up some comments on it.

I see the a15mpcore.c code is based on a version of mpcore.c
which predates the MemoryRegion API changes -- we'll need to
update it to use MemoryRegions.


OK, I will make it updated.

There are some relics of 11MPCore peripherals lurking in there
which need to be taken out. (I think we should probably clean
up mpcore.c to separate out A9 from 11MPCore, incidentally.)

The vexpress A9 and A15 init functions can probably share
code although I haven't looked too closely there.

Neither did I :)
Anyway I will dig the code harder.


For QEMU TCG we're going to want to model at least some
of the cp15 registers (although probably mostly dummy
implementations).


I'm not focusing on this by now, if this a MUST, I will try to do it.

The A15 generic timer is accessed via cp15 registers rather
than being memory mapped -- we need to decide which side of
the KVM/QEMU boundary the model of that should live. (I'm
guessing the right answer is qemu side which means we'll
need an ABI between KVM and QEMU to pass (some) cp15 accesses
through.)


right!

Current arch timer implementation will first check whether arch timer is 
implemented

*AND* whether arch timer frequency is set by security firmware.
If no arch timer available, SP804 will be used as clock source/event, 
that's what I am

using so far.

If generic timer need to be supported, this will fall into QEMU side, 
with the help of KVM
trapping any cp15 timer access. Anther issue is virtual timer support, I 
haven't make a
clear picture how virtual timer hardware fit into KVM smoothly, so let's 
focus on what

you proposed.

Anyway thanks for your suggestions, I will move on to next version to 
review :)




thanks again
-- PMM



--
I am a slow learner
but I will keep trying to fight for my dreams!

--bill




[Qemu-devel] [PATCH] Add Qemu A15 minimal support for ARM KVM

2011-09-29 Thread bill4carson
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
+++