qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PULL 38/58] arm11mpcore: Split off SCU device


From: Andreas Färber
Subject: [Qemu-devel] [PULL 38/58] arm11mpcore: Split off SCU device
Date: Tue, 8 Oct 2013 19:44:36 +0200

Inspired by a9scu.

Reviewed-by: Peter Maydell <address@hidden>
Signed-off-by: Andreas Färber <address@hidden>
---
 default-configs/arm-softmmu.mak |   1 +
 hw/cpu/arm11mpcore.c            |  65 ++++++--------------------
 hw/misc/Makefile.objs           |   1 +
 hw/misc/arm11scu.c              | 100 ++++++++++++++++++++++++++++++++++++++++
 include/hw/misc/arm11scu.h      |  29 ++++++++++++
 5 files changed, 145 insertions(+), 51 deletions(-)
 create mode 100644 hw/misc/arm11scu.c
 create mode 100644 include/hw/misc/arm11scu.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index ac0815d..52d263a 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -62,6 +62,7 @@ CONFIG_BITBANG_I2C=y
 CONFIG_FRAMEBUFFER=y
 CONFIG_XILINX_SPIPS=y
 
+CONFIG_ARM11SCU=y
 CONFIG_A9SCU=y
 CONFIG_MARVELL_88W8618=y
 CONFIG_OMAP=y
diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c
index 5f80e7b..5dcc73a 100644
--- a/hw/cpu/arm11mpcore.c
+++ b/hw/cpu/arm11mpcore.c
@@ -8,6 +8,7 @@
  */
 
 #include "hw/sysbus.h"
+#include "hw/misc/arm11scu.h"
 #include "qemu/timer.h"
 
 /* MPCore private memory region.  */
@@ -19,64 +20,18 @@
 typedef struct ARM11MPCorePriveState {
     SysBusDevice parent_obj;
 
-    uint32_t scu_control;
     uint32_t num_cpu;
-    MemoryRegion iomem;
     MemoryRegion container;
     DeviceState *mptimer;
     DeviceState *wdtimer;
     DeviceState *gic;
     uint32_t num_irq;
+
+    ARM11SCUState scu;
 } ARM11MPCorePriveState;
 
 /* Per-CPU private memory mapped IO.  */
 
-static uint64_t mpcore_scu_read(void *opaque, hwaddr offset,
-                                unsigned size)
-{
-    ARM11MPCorePriveState *s = (ARM11MPCorePriveState *)opaque;
-    int id;
-    /* SCU */
-    switch (offset) {
-    case 0x00: /* Control.  */
-        return s->scu_control;
-    case 0x04: /* Configuration.  */
-        id = ((1 << s->num_cpu) - 1) << 4;
-        return id | (s->num_cpu - 1);
-    case 0x08: /* CPU status.  */
-        return 0;
-    case 0x0c: /* Invalidate all.  */
-        return 0;
-    default:
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "mpcore_priv_read: Bad offset %x\n", (int)offset);
-        return 0;
-    }
-}
-
-static void mpcore_scu_write(void *opaque, hwaddr offset,
-                             uint64_t value, unsigned size)
-{
-    ARM11MPCorePriveState *s = (ARM11MPCorePriveState *)opaque;
-    /* SCU */
-    switch (offset) {
-    case 0: /* Control register.  */
-        s->scu_control = value & 1;
-        break;
-    case 0x0c: /* Invalidate all.  */
-        /* This is a no-op as cache is not emulated.  */
-        break;
-    default:
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "mpcore_priv_read: Bad offset %x\n", (int)offset);
-    }
-}
-
-static const MemoryRegionOps mpcore_scu_ops = {
-    .read = mpcore_scu_read,
-    .write = mpcore_scu_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-};
 
 static void mpcore_priv_set_irq(void *opaque, int irq, int level)
 {
@@ -87,12 +42,13 @@ static void mpcore_priv_set_irq(void *opaque, int irq, int 
level)
 static void mpcore_priv_map_setup(ARM11MPCorePriveState *s)
 {
     int i;
+    SysBusDevice *scubusdev = SYS_BUS_DEVICE(&s->scu);
     SysBusDevice *gicbusdev = SYS_BUS_DEVICE(s->gic);
     SysBusDevice *timerbusdev = SYS_BUS_DEVICE(s->mptimer);
     SysBusDevice *wdtbusdev = SYS_BUS_DEVICE(s->wdtimer);
-    memory_region_init_io(&s->iomem, OBJECT(s),
-                          &mpcore_scu_ops, s, "mpcore-scu", 0x100);
-    memory_region_add_subregion(&s->container, 0, &s->iomem);
+
+    memory_region_add_subregion(&s->container, 0,
+                                sysbus_mmio_get_region(scubusdev, 0));
     /* GIC CPU interfaces: "current CPU" at 0x100, then specific CPUs
      * at 0x200, 0x300...
      */
@@ -130,6 +86,10 @@ static int mpcore_priv_init(SysBusDevice *sbd)
 {
     DeviceState *dev = DEVICE(sbd);
     ARM11MPCorePriveState *s = ARM11MPCORE_PRIV(dev);
+    DeviceState *scudev = DEVICE(&s->scu);
+
+    qdev_prop_set_uint32(scudev, "num-cpu", s->num_cpu);
+    qdev_init_nofail(scudev);
 
     s->gic = qdev_create(NULL, "arm_gic");
     qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
@@ -164,6 +124,9 @@ static void mpcore_priv_initfn(Object *obj)
     memory_region_init(&s->container, OBJECT(s),
                        "mpcore-priv-container", 0x2000);
     sysbus_init_mmio(sbd, &s->container);
+
+    object_initialize(&s->scu, sizeof(s->scu), TYPE_ARM11_SCU);
+    qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
 }
 
 #define TYPE_REALVIEW_MPCORE_RIRQ "realview_mpcore"
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 5636299..a30bf5e 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -11,6 +11,7 @@ obj-$(CONFIG_VMPORT) += vmport.o
 # ARM devices
 common-obj-$(CONFIG_PL310) += arm_l2x0.o
 common-obj-$(CONFIG_A9SCU) += a9scu.o
+common-obj-$(CONFIG_ARM11SCU) += arm11scu.o
 
 # PKUnity SoC devices
 common-obj-$(CONFIG_PUV3) += puv3_pm.o
diff --git a/hw/misc/arm11scu.c b/hw/misc/arm11scu.c
new file mode 100644
index 0000000..a791675
--- /dev/null
+++ b/hw/misc/arm11scu.c
@@ -0,0 +1,100 @@
+/*
+ * ARM11MPCore Snoop Control Unit (SCU) emulation
+ *
+ * Copyright (c) 2006-2007 CodeSourcery.
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ * Written by Paul Brook and Andreas Färber
+ *
+ * This code is licensed under the GPL.
+ */
+
+#include "hw/misc/arm11scu.h"
+
+static uint64_t mpcore_scu_read(void *opaque, hwaddr offset,
+                                unsigned size)
+{
+    ARM11SCUState *s = (ARM11SCUState *)opaque;
+    int id;
+    /* SCU */
+    switch (offset) {
+    case 0x00: /* Control.  */
+        return s->control;
+    case 0x04: /* Configuration.  */
+        id = ((1 << s->num_cpu) - 1) << 4;
+        return id | (s->num_cpu - 1);
+    case 0x08: /* CPU status.  */
+        return 0;
+    case 0x0c: /* Invalidate all.  */
+        return 0;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "mpcore_priv_read: Bad offset %x\n", (int)offset);
+        return 0;
+    }
+}
+
+static void mpcore_scu_write(void *opaque, hwaddr offset,
+                             uint64_t value, unsigned size)
+{
+    ARM11SCUState *s = (ARM11SCUState *)opaque;
+    /* SCU */
+    switch (offset) {
+    case 0: /* Control register.  */
+        s->control = value & 1;
+        break;
+    case 0x0c: /* Invalidate all.  */
+        /* This is a no-op as cache is not emulated.  */
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "mpcore_priv_read: Bad offset %x\n", (int)offset);
+    }
+}
+
+static const MemoryRegionOps mpcore_scu_ops = {
+    .read = mpcore_scu_read,
+    .write = mpcore_scu_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void arm11_scu_realize(DeviceState *dev, Error **errp)
+{
+}
+
+static void arm11_scu_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    ARM11SCUState *s = ARM11_SCU(obj);
+
+    memory_region_init_io(&s->iomem, OBJECT(s),
+                          &mpcore_scu_ops, s, "mpcore-scu", 0x100);
+    sysbus_init_mmio(sbd, &s->iomem);
+}
+
+static Property arm11_scu_properties[] = {
+    DEFINE_PROP_UINT32("num-cpu", ARM11SCUState, num_cpu, 1),
+    DEFINE_PROP_END_OF_LIST()
+};
+
+static void arm11_scu_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = arm11_scu_realize;
+    dc->props = arm11_scu_properties;
+}
+
+static const TypeInfo arm11_scu_type_info = {
+    .name          = TYPE_ARM11_SCU,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(ARM11SCUState),
+    .instance_init = arm11_scu_init,
+    .class_init    = arm11_scu_class_init,
+};
+
+static void arm11_scu_register_types(void)
+{
+    type_register_static(&arm11_scu_type_info);
+}
+
+type_init(arm11_scu_register_types)
diff --git a/include/hw/misc/arm11scu.h b/include/hw/misc/arm11scu.h
new file mode 100644
index 0000000..5ad0f3d
--- /dev/null
+++ b/include/hw/misc/arm11scu.h
@@ -0,0 +1,29 @@
+/*
+ * ARM11MPCore Snoop Control Unit (SCU) emulation
+ *
+ * Copyright (c) 2006-2007 CodeSourcery.
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ * Written by Paul Brook and Andreas Färber
+ *
+ * This code is licensed under the GPL.
+ */
+
+#ifndef HW_MISC_ARM11SCU_H
+#define HW_MISC_ARM11SCU_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_ARM11_SCU "arm11-scu"
+#define ARM11_SCU(obj) OBJECT_CHECK(ARM11SCUState, (obj), TYPE_ARM11_SCU)
+
+typedef struct ARM11SCUState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    uint32_t control;
+    uint32_t num_cpu;
+    MemoryRegion iomem;
+} ARM11SCUState;
+
+#endif
-- 
1.8.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]