qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [Patch] ARM: Add an L2 cache controller to KZM


From: Peter Chubb
Subject: Re: [Qemu-devel] [Patch] ARM: Add an L2 cache controller to KZM
Date: Wed, 07 Aug 2013 12:21:46 +1000
User-agent: Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM/1.14.9 (Gojō) APEL/10.8 EasyPG/1.0.0 Emacs/23.4 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO)

OK, this is what I've come up with.  Dunno whether it's right or not
-- the object model is decoupled from the memory model, so  there's no
straightforward way to override just a few of the registers.

At this stage this is just for comment, as I don't really have that
much of a clue about how the object/class hierarchy is meant to work.

---
 hw/arm/kzm.c       |    3 +
 hw/misc/arm_l2x0.c |  129 ++++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 96 insertions(+), 36 deletions(-)

Index: qemu/hw/arm/kzm.c
===================================================================
--- qemu.orig/hw/arm/kzm.c      2013-08-07 11:21:48.864692846 +1000
+++ qemu/hw/arm/kzm.c   2013-08-07 11:22:40.292983604 +1000
@@ -33,6 +33,7 @@
      * 0x1fffc000-0x1fffffff RAM                  EMULATED
      * 0x20000000-0x2fffffff Reserved             IGNORED
      * 0x30000000-0x7fffffff I.MX31 Internal Register Space
+     *   0x30000000-0x30000fff L2 Cache Controller PARTIALLY EMULATED
      *   0x43f00000 IO_AREA0
      *   0x43f90000 UART1                         EMULATED
      *   0x43f94000 UART2                         EMULATED
@@ -134,6 +135,8 @@ static void kzm_init(QEMUMachineInitArgs
                        DEVICE_NATIVE_ENDIAN);
     }
 
+    sysbus_create_varargs("imx_l2cc", 0x30000000, NULL);
+
     kzm_binfo.ram_size = ram_size;
     kzm_binfo.kernel_filename = kernel_filename;
     kzm_binfo.kernel_cmdline = kernel_cmdline;
Index: qemu/hw/misc/arm_l2x0.c
===================================================================
--- qemu.orig/hw/misc/arm_l2x0.c        2013-08-07 11:21:48.864692846 +1000
+++ qemu/hw/misc/arm_l2x0.c     2013-08-07 11:21:48.860692824 +1000
@@ -21,7 +21,9 @@
 #include "hw/sysbus.h"
 
 /* L2C-310 r3p2 */
-#define CACHE_ID 0x410000c8
+#define PL310_CACHE_ID 0x410000c8
+/* L2CC from Freescale */
+#define IMX_PL2CC_CACHE_ID 0xD5000041
 
 #define TYPE_ARM_L2X0 "l2x0"
 #define ARM_L2X0(obj) OBJECT_CHECK(L2x0State, (obj), TYPE_ARM_L2X0)
@@ -30,6 +32,7 @@ typedef struct L2x0State {
     SysBusDevice parent_obj;
 
     MemoryRegion iomem;
+    uint32_t cache_id;
     uint32_t cache_type;
     uint32_t ctrl;
     uint32_t aux_ctrl;
@@ -66,7 +69,7 @@ static uint64_t l2x0_priv_read(void *opa
     }
     switch (offset) {
     case 0:
-        return CACHE_ID;
+        return s->cache_id;
     case 0x4:
         /* aux_ctrl values affect cache_type values */
         cache_data = (s->aux_ctrl & (7 << 17)) >> 15;
@@ -78,23 +81,25 @@ static uint64_t l2x0_priv_read(void *opa
         return s->aux_ctrl;
     case 0x108:
         return s->tag_ctrl;
-    case 0x10C:
-        return s->data_ctrl;
-    case 0xC00:
-        return s->filter_start;
-    case 0xC04:
-        return s->filter_end;
     case 0xF40:
         return 0;
-    case 0xF60:
-        return 0;
-    case 0xF80:
-        return 0;
-    default:
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "l2x0_priv_read: Bad offset %x\n", (int)offset);
-        break;
     }
+    if (s->cache_id == PL310_CACHE_ID) {
+        switch (offset) {
+        case 0x10C:
+            return s->data_ctrl;
+        case 0xC00:
+            return s->filter_start;
+        case 0xC04:
+            return s->filter_end;
+        case 0xF60:
+            return 0;
+        case 0xF80:
+            return 0;
+        }
+    }
+    qemu_log_mask(LOG_GUEST_ERROR,
+                      "l2x0_priv_read: Bad offset %x\n", (int)offset);
     return 0;
 }
 
@@ -107,6 +112,7 @@ static void l2x0_priv_write(void *opaque
         /* ignore */
         return;
     }
+
     switch (offset) {
     case 0x100:
         s->ctrl = value & 1;
@@ -114,29 +120,32 @@ static void l2x0_priv_write(void *opaque
     case 0x104:
         s->aux_ctrl = value;
         break;
-    case 0x108:
-        s->tag_ctrl = value;
-        break;
-    case 0x10C:
-        s->data_ctrl = value;
-        break;
-    case 0xC00:
-        s->filter_start = value;
-        break;
-    case 0xC04:
-        s->filter_end = value;
-        break;
     case 0xF40:
         return;
-    case 0xF60:
-        return;
-    case 0xF80:
-        return;
-    default:
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "l2x0_priv_write: Bad offset %x\n", (int)offset);
-        break;
     }
+
+    if (s->cache_id == PL310_CACHE_ID) {
+        switch (offset) {
+        case 0x108:
+            s->tag_ctrl = value;
+            break;
+        case 0x10C:
+            s->data_ctrl = value;
+            break;
+        case 0xC00:
+            s->filter_start = value;
+            break;
+        case 0xC04:
+            s->filter_end = value;
+            break;
+        case 0xF60:
+            return;
+        case 0xF80:
+            return;
+        }
+    }
+    qemu_log_mask(LOG_GUEST_ERROR,
+                      "l2x0_priv_write: Bad offset %x\n", (int)offset);
 }
 
 static void l2x0_priv_reset(DeviceState *dev)
@@ -184,16 +193,64 @@ static void l2x0_class_init(ObjectClass
     dc->reset = l2x0_priv_reset;
 }
 
+static void l2x0_init(Object *obj)
+{
+    L2x0State *s = ARM_L2X0(obj);
+
+    s->cache_id = PL310_CACHE_ID;
+}
+
 static const TypeInfo l2x0_info = {
     .name = TYPE_ARM_L2X0,
     .parent = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(L2x0State),
+    .instance_init = l2x0_init,
     .class_init = l2x0_class_init,
 };
 
+/********************************
+ * The i.MX31 L2CC is a subset of the PL310 implemented above.
+ */
+
+static void imx_l2cc_init(Object *obj) {
+    L2x0State *s = ARM_L2X0(obj);
+
+    s->cache_id = IMX_PL2CC_CACHE_ID;
+}
+
+
+static void imx_l2cc_priv_reset(DeviceState *dev)
+{
+    L2x0State *s = ARM_L2X0(dev);
+
+    s->ctrl = 0;
+    s->aux_ctrl = 0xE4020FFF;
+}
+
+
+/*
+ * I assume the parent class's init function has already been called.
+ */
+static void imx_l2cc_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = imx_l2cc_priv_reset;
+}
+
+
+static const TypeInfo imx_l2cc_info = {
+    .name = "imx_l2cc",
+    .parent = TYPE_ARM_L2X0,
+    .instance_init = imx_l2cc_init,
+    .class_init = imx_l2cc_class_init,
+};
+
+
 static void l2x0_register_types(void)
 {
     type_register_static(&l2x0_info);
+    type_register_static(&imx_l2cc_info);
 }
 
 type_init(l2x0_register_types)



reply via email to

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