qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v5 0/7] various ARM fixes for Calxeda Highbank
@ 2011-12-29 16:19 Mark Langsdorf
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 1/7] arm: add missing scu registers Mark Langsdorf
                   ` (6 more replies)
  0 siblings, 7 replies; 26+ messages in thread
From: Mark Langsdorf @ 2011-12-29 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, afaerber, rob.herring

This is a collection of fixes and additions to the models for various
ARM devices. These changes are needed to support the forthcoming 
Calxeda Highbank SoC model.

 Makefile.target     |    2 +
 hw/a9mpcore.c       |   43 +++++-
 hw/arm11mpcore.c    |   14 +-
 hw/arm_gic.c        |   63 +++++---
 hw/arm_l2x0.c       |  182 ++++++++++++++++++++++
 hw/arm_timer.c      |   24 +++-
 hw/armv7m_nvic.c    |    7 +-
 hw/realview_gic.c   |    3 +-
 hw/xgmac.c          |  424 +++++++++++++++++++++++++++++++++++++++++++++++++++
 target-arm/cpu.h    |    1 +
 target-arm/helper.c |   14 ++
 11 files changed, 729 insertions(+), 48 deletions(-)

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [Qemu-devel] [PATCH v5 1/7] arm: add missing scu registers
  2011-12-29 16:19 [Qemu-devel] [PATCH v5 0/7] various ARM fixes for Calxeda Highbank Mark Langsdorf
@ 2011-12-29 16:19 ` Mark Langsdorf
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 2/7] arm: Set frequencies for arm_timer Mark Langsdorf
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 26+ messages in thread
From: Mark Langsdorf @ 2011-12-29 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Mark Langsdorf, afaerber, rob.herring

From: Rob Herring <rob.herring@calxeda.com>

Add power control register to a9mpcore

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
Changes from v3, v4
	None
Changes from v2:
        Better handling of byte and halfword writes to the power register
        Correct handling of VMState versions
        Improved commit message
Changes from v1:
        Added VMState support
        Checked alignment of writes to the power control register

 hw/a9mpcore.c |   36 +++++++++++++++++++++++++++++++++---
 1 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index cd2985f..3ef0e13 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -29,6 +29,7 @@ gic_get_current_cpu(void)
 typedef struct a9mp_priv_state {
     gic_state gic;
     uint32_t scu_control;
+    uint32_t scu_status;
     uint32_t old_timer_status[8];
     uint32_t num_cpu;
     qemu_irq *timer_irq;
@@ -48,7 +49,13 @@ static uint64_t a9_scu_read(void *opaque, target_phys_addr_t offset,
     case 0x04: /* Configuration */
         return (((1 << s->num_cpu) - 1) << 4) | (s->num_cpu - 1);
     case 0x08: /* CPU Power Status */
-        return 0;
+        return s->scu_status;
+    case 0x09: /* CPU status.  */
+        return s->scu_status >> 8;
+    case 0x0a: /* CPU status.  */
+        return s->scu_status >> 16;
+    case 0x0b: /* CPU status.  */
+        return s->scu_status >> 24;
     case 0x0c: /* Invalidate All Registers In Secure State */
         return 0;
     case 0x40: /* Filtering Start Address Register */
@@ -67,12 +74,35 @@ static void a9_scu_write(void *opaque, target_phys_addr_t offset,
                          uint64_t value, unsigned size)
 {
     a9mp_priv_state *s = (a9mp_priv_state *)opaque;
+    uint32_t mask;
+    uint32_t shift;
+    switch (size) {
+    case 1:
+        mask = 0xff;
+        break;
+    case 2:
+        mask = 0xffff;
+        break;
+    case 4:
+        mask = 0xffffffff;
+        break;
+    default:
+        fprintf(stderr, "Invalid size %u in write to a9 scu register %x\n",
+                size, offset);
+        return;
+    }
+
     switch (offset) {
     case 0x00: /* Control */
         s->scu_control = value & 1;
         break;
     case 0x4: /* Configuration: RO */
         break;
+    case 0x08: case 0x09: case 0x0A: case 0x0B: /* Power Control */
+        shift = (offset - 0x8) * 8;
+        s->scu_status &= ~(mask << shift);
+        s->scu_status |= ((value & mask) << shift);
+        break;
     case 0x0c: /* Invalidate All Registers In Secure State */
         /* no-op as we do not implement caches */
         break;
@@ -80,7 +110,6 @@ static void a9_scu_write(void *opaque, target_phys_addr_t offset,
     case 0x44: /* Filtering End Address Register */
         /* RAZ/WI, like an implementation with only one AXI master */
         break;
-    case 0x8: /* CPU Power Status */
     case 0x50: /* SCU Access Control Register */
     case 0x54: /* SCU Non-secure Access Control Register */
         /* unimplemented, fall through */
@@ -169,11 +198,12 @@ static int a9mp_priv_init(SysBusDevice *dev)
 
 static const VMStateDescription vmstate_a9mp_priv = {
     .name = "a9mpcore_priv",
-    .version_id = 1,
+    .version_id = 2,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(scu_control, a9mp_priv_state),
         VMSTATE_UINT32_ARRAY(old_timer_status, a9mp_priv_state, 8),
+        VMSTATE_UINT32_V(scu_status, a9mp_priv_state, 2),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [Qemu-devel] [PATCH v5 2/7] arm: Set frequencies for arm_timer
  2011-12-29 16:19 [Qemu-devel] [PATCH v5 0/7] various ARM fixes for Calxeda Highbank Mark Langsdorf
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 1/7] arm: add missing scu registers Mark Langsdorf
@ 2011-12-29 16:19 ` Mark Langsdorf
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 3/7] arm: add dummy v7 cp15 config_base_register Mark Langsdorf
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 26+ messages in thread
From: Mark Langsdorf @ 2011-12-29 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Mark Langsdorf, afaerber, rob.herring

Use qdev properties to allow board modelers to set the frequencies
for the sp804 timer. Each of the sp804's timers can have an
individual frequency. The timers default to 1MHz.

Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andreas Färber <afaerber@suse.de>
---
Changes from v3, v4
	None
Changes from v2
        Comment correctly describes behavior of properties
        freqX variables are defined as uint32_t, not int
Changes from v1
        Simplified multiple timer frequency handling
        Removed the shared default

 hw/arm_timer.c |   24 +++++++++++++++++++-----
 1 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index 0a5b9d2..60e1c63 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -9,6 +9,8 @@
 
 #include "sysbus.h"
 #include "qemu-timer.h"
+#include "qemu-common.h"
+#include "qdev.h"
 
 /* Common timer implementation.  */
 
@@ -178,6 +180,7 @@ typedef struct {
     SysBusDevice busdev;
     MemoryRegion iomem;
     arm_timer_state *timer[2];
+    uint32_t freq0, freq1;
     int level[2];
     qemu_irq irq;
 } sp804_state;
@@ -269,10 +272,11 @@ static int sp804_init(SysBusDevice *dev)
 
     qi = qemu_allocate_irqs(sp804_set_irq, s, 2);
     sysbus_init_irq(dev, &s->irq);
-    /* ??? The timers are actually configurable between 32kHz and 1MHz, but
-       we don't implement that.  */
-    s->timer[0] = arm_timer_init(1000000);
-    s->timer[1] = arm_timer_init(1000000);
+    /* The timers are configurable between 32kHz and 1MHz
+     * defaulting to 1MHz but overrideable as individual properties */
+    s->timer[0] = arm_timer_init(s->freq0);
+    s->timer[1] = arm_timer_init(s->freq1);
+
     s->timer[0]->irq = qi[0];
     s->timer[1]->irq = qi[1];
     memory_region_init_io(&s->iomem, &sp804_ops, s, "sp804", 0x1000);
@@ -281,6 +285,16 @@ static int sp804_init(SysBusDevice *dev)
     return 0;
 }
 
+static SysBusDeviceInfo sp804_info = {
+    .init = sp804_init,
+    .qdev.name = "sp804",
+    .qdev.size = sizeof(sp804_state),
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("freq0", sp804_state, freq0, 1000000),
+        DEFINE_PROP_UINT32("freq1", sp804_state, freq1, 1000000),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
 
 /* Integrator/CP timer module.  */
 
@@ -349,7 +363,7 @@ static int icp_pit_init(SysBusDevice *dev)
 static void arm_timer_register_devices(void)
 {
     sysbus_register_dev("integrator_pit", sizeof(icp_pit_state), icp_pit_init);
-    sysbus_register_dev("sp804", sizeof(sp804_state), sp804_init);
+    sysbus_register_withprop(&sp804_info);
 }
 
 device_init(arm_timer_register_devices)
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [Qemu-devel] [PATCH v5 3/7] arm: add dummy v7 cp15 config_base_register
  2011-12-29 16:19 [Qemu-devel] [PATCH v5 0/7] various ARM fixes for Calxeda Highbank Mark Langsdorf
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 1/7] arm: add missing scu registers Mark Langsdorf
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 2/7] arm: Set frequencies for arm_timer Mark Langsdorf
@ 2011-12-29 16:19 ` Mark Langsdorf
  2012-01-04 14:32   ` Peter Maydell
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 4/7] arm: add dummy gic security registers Mark Langsdorf
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 26+ messages in thread
From: Mark Langsdorf @ 2011-12-29 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Mark Langsdorf, afaerber, rob.herring

Add a cp15 config_base_register that currently defaults to 0.
After the QOM CPU support is added, the value will be properly
set to the periphal base value.

Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
Changes from v3, v4
	None
Changes from v2
        Added test against op2 
Changes from v1
        renamed the register
        added comments about how it will change when QOM CPUs are added

 target-arm/cpu.h    |    1 +
 target-arm/helper.c |   14 ++++++++++++++
 2 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c4d742f..449e620 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -149,6 +149,7 @@ typedef struct CPUARMState {
         uint32_t c15_i_max; /* Maximum D-cache dirty line index.  */
         uint32_t c15_i_min; /* Minimum D-cache dirty line index.  */
         uint32_t c15_threadid; /* TI debugger thread-ID.  */
+        uint32_t c15_config_base_address; /* SCU base address.  */
     } cp15;
 
     struct {
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 65f4fbf..b235fed 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2111,6 +2111,20 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
              * 0x200 << ($rn & 0xfff), when MMU is off.  */
             goto bad_reg;
         }
+        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
+            switch (crm) {
+            case 0:
+                /* The config_base_address should hold the value of
+                 * the peripheral base. ARM should get this from a CPU
+                 * object property, but that support isn't available in
+                 * December 2011. Default to 0 for now and board models
+                 * that care can set it by a private hook */
+                if ((op1 == 4) && (op2 == 0)) {
+                    return env->cp15.c15_config_base_address;
+                }
+            }
+            goto bad_reg;
+        }
         return 0;
     }
 bad_reg:
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [Qemu-devel] [PATCH v5 4/7] arm: add dummy gic security registers
  2011-12-29 16:19 [Qemu-devel] [PATCH v5 0/7] various ARM fixes for Calxeda Highbank Mark Langsdorf
                   ` (2 preceding siblings ...)
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 3/7] arm: add dummy v7 cp15 config_base_register Mark Langsdorf
@ 2011-12-29 16:19 ` Mark Langsdorf
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 5/5] add L2x0/PL310 cache controller device Mark Langsdorf
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 26+ messages in thread
From: Mark Langsdorf @ 2011-12-29 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Mark Langsdorf, afaerber, rob.herring

From: Rob Herring <rob.herring@calxeda.com>

Implement handling for the RAZ/WI gic security registers.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
Changes from v2, v3, v4
        None
Changes from v1
        Moved handling back inside the 0-0x100 block
        Added more clarifying comments

 hw/arm_gic.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 9b52119..0339cf5 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -282,6 +282,10 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
             return ((GIC_NIRQ / 32) - 1) | ((NUM_CPU(s) - 1) << 5);
         if (offset < 0x08)
             return 0;
+        if (offset >= 0x80) {
+            /* Interrupt Security , RAZ/WI */
+            return 0;
+        }
 #endif
         goto bad_reg;
     } else if (offset < 0x200) {
@@ -413,6 +417,8 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
             DPRINTF("Distribution %sabled\n", s->enabled ? "En" : "Dis");
         } else if (offset < 4) {
             /* ignored.  */
+        } else if (offset >= 0x80) {
+            /* Interrupt Security Registers, RAZ/WI */
         } else {
             goto bad_reg;
         }
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [Qemu-devel] [PATCH v5 5/5] add L2x0/PL310 cache controller device
  2011-12-29 16:19 [Qemu-devel] [PATCH v5 0/7] various ARM fixes for Calxeda Highbank Mark Langsdorf
                   ` (3 preceding siblings ...)
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 4/7] arm: add dummy gic security registers Mark Langsdorf
@ 2011-12-29 16:19 ` Mark Langsdorf
  2012-01-04 13:29   ` Peter Maydell
  2012-06-07 13:45   ` Andreas Färber
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 6/7] Add xgmac ethernet model Mark Langsdorf
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 7/7] arm: make the number of GIC interrupts configurable Mark Langsdorf
  6 siblings, 2 replies; 26+ messages in thread
From: Mark Langsdorf @ 2011-12-29 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Mark Langsdorf, afaerber, rob.herring

From: Rob Herring <rob.herring@calxeda.com>

This is just a dummy device for ARM L2 cache controllers, based on the
pl310. The cache type parameter can be defined by a property value
and has a meaningful default.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
Changes from v4
	Handling cache_type bits tracked from aux_control in the read function,
	not the write function
Changes from v3
        Changed default value
        Adding tracking of cache_type bits from aux_control
Changes from v2
        Reformatted a couple of function definitions to be 80 lines long
Changes from v1
        Corrected formatting
        Clarified the copyrights
        Clarified GPL revision
        Clarified model version
        Removed hw_error() calls
        Added a reset function
        Restructed everything as switch/case statements
        Added a type cache property

 Makefile.target |    1 +
 hw/arm_l2x0.c   |  182 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 183 insertions(+), 0 deletions(-)
 create mode 100644 hw/arm_l2x0.c

diff --git a/Makefile.target b/Makefile.target
index 3261383..db5e44c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -336,6 +336,7 @@ 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 += arm_l2x0.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
 obj-arm-y += pl061.o
diff --git a/hw/arm_l2x0.c b/hw/arm_l2x0.c
new file mode 100644
index 0000000..ba106f1
--- /dev/null
+++ b/hw/arm_l2x0.c
@@ -0,0 +1,182 @@
+/*
+ * ARM dummy L210, L220, PL310 cache controller.
+ *
+ * Copyright (c) 2010-2012 Calxeda
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or any later version, as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope 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/>.
+ *
+ */
+
+#include "sysbus.h"
+
+/* L2C-310 r3p2 */
+#define CACHE_ID 0x410000c8
+
+typedef struct l2x0_state {
+    SysBusDevice busdev;
+    MemoryRegion iomem;
+    uint32_t cache_type;
+    uint32_t ctrl;
+    uint32_t aux_ctrl;
+    uint32_t data_ctrl;
+    uint32_t tag_ctrl;
+    uint32_t filter_start;
+    uint32_t filter_end;
+} l2x0_state;
+
+static const VMStateDescription vmstate_l2x0 = {
+    .name = "l2x0",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(ctrl, l2x0_state),
+        VMSTATE_UINT32(aux_ctrl, l2x0_state),
+        VMSTATE_UINT32(data_ctrl, l2x0_state),
+        VMSTATE_UINT32(tag_ctrl, l2x0_state),
+        VMSTATE_UINT32(filter_start, l2x0_state),
+        VMSTATE_UINT32(filter_end, l2x0_state),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+
+static uint64_t l2x0_priv_read(void *opaque, target_phys_addr_t offset,
+                               unsigned size)
+{
+    uint32_t cache_data;
+    l2x0_state *s = (l2x0_state *)opaque;
+    offset &= 0xfff;
+    if (offset >= 0x730 && offset < 0x800) {
+        return 0; /* cache ops complete */
+    }
+    switch (offset) {
+    case 0:
+        return CACHE_ID;
+    case 0x4:
+        /* aux_ctrl values affect cache_type values */
+        cache_data = (s->aux_ctrl & (7 << 17)) >> 15;
+        cache_data |= (s->aux_ctrl & (1 << 16)) >> 16;
+        return s->cache_type |= (cache_data << 18) | (cache_data << 6);
+    case 0x100:
+        return s->ctrl;
+    case 0x104:
+        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:
+        fprintf(stderr, "l2x0_priv_read: Bad offset %x\n", (int)offset);
+        break;
+    }
+    return 0;
+}
+
+static void l2x0_priv_write(void *opaque, target_phys_addr_t offset,
+                            uint64_t value, unsigned size)
+{
+    l2x0_state *s = (l2x0_state *)opaque;
+    offset &= 0xfff;
+    if (offset >= 0x730 && offset < 0x800) {
+        /* ignore */
+        return;
+    }
+    switch (offset) {
+    case 0x100:
+        s->ctrl = value & 1;
+        break;
+    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:
+        fprintf(stderr, "l2x0_priv_write: Bad offset %x\n", (int)offset);
+        break;
+    }
+}
+
+static void l2x0_priv_reset(DeviceState *dev)
+{
+    l2x0_state *s = DO_UPCAST(l2x0_state, busdev.qdev, dev);
+
+    s->ctrl = 0;
+    s->aux_ctrl = 0x02020000;
+    s->tag_ctrl = 0;
+    s->data_ctrl = 0;
+    s->filter_start = 0;
+    s->filter_end = 0;
+}
+
+static const MemoryRegionOps l2x0_mem_ops = {
+    .read = l2x0_priv_read,
+    .write = l2x0_priv_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+ };
+
+static int l2x0_priv_init(SysBusDevice *dev)
+{
+    l2x0_state *s = FROM_SYSBUS(l2x0_state, dev);
+
+    memory_region_init_io(&s->iomem, &l2x0_mem_ops, s, "l2x0_cc", 0x1000);
+    sysbus_init_mmio(dev, &s->iomem);
+    return 0;
+}
+
+static SysBusDeviceInfo l2x0_info = {
+    .init = l2x0_priv_init,
+    .qdev.name = "l2x0",
+    .qdev.size = sizeof(l2x0_state),
+    .qdev.vmsd = &vmstate_l2x0,
+    .qdev.no_user = 1,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("type", l2x0_state, cache_type, 0x1c100100),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+    .qdev.reset = l2x0_priv_reset,
+};
+
+static void l2x0_register_device(void)
+{
+    sysbus_register_withprop(&l2x0_info);
+}
+
+device_init(l2x0_register_device)
+
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [Qemu-devel] [PATCH v5 6/7] Add xgmac ethernet model
  2011-12-29 16:19 [Qemu-devel] [PATCH v5 0/7] various ARM fixes for Calxeda Highbank Mark Langsdorf
                   ` (4 preceding siblings ...)
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 5/5] add L2x0/PL310 cache controller device Mark Langsdorf
@ 2011-12-29 16:19 ` Mark Langsdorf
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 7/7] arm: make the number of GIC interrupts configurable Mark Langsdorf
  6 siblings, 0 replies; 26+ messages in thread
From: Mark Langsdorf @ 2011-12-29 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Mark Langsdorf, afaerber, rob.herring

This adds very basic support for XG-mac ethernet core from Synopsis and
others. Missing things include:

- statistics counters
- WoL support
- rx checksum offload
- chained descriptors (only linear descriptor ring)
- broadcast and multicast handling

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
Changes from v4
	None
Changes from v3
        Added debug macro and cleaned up some debug code
        Refitted all lines to fit within 80 columns
Changes from v2
        None
Changes from v1
        Reformated most lines to fit within 80 columns
        Removed a bunch of unused variables in the state structures
        Got rid of some camelcase structure names
        Added vmstate support

 Makefile.target |    1 +
 hw/xgmac.c      |  424 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 425 insertions(+), 0 deletions(-)
 create mode 100644 hw/xgmac.c

diff --git a/Makefile.target b/Makefile.target
index db5e44c..94cb9ff 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -340,6 +340,7 @@ obj-arm-y += arm_l2x0.o
 obj-arm-y += arm_mptimer.o
 obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
 obj-arm-y += pl061.o
+obj-arm-y += xgmac.o
 obj-arm-y += arm-semi.o
 obj-arm-y += pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
 obj-arm-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
diff --git a/hw/xgmac.c b/hw/xgmac.c
new file mode 100644
index 0000000..c19fff5
--- /dev/null
+++ b/hw/xgmac.c
@@ -0,0 +1,424 @@
+/*
+ * QEMU model of XGMAC Ethernet.
+ *
+ * derived from the Xilinx AXI-Ethernet by Edgar E. Iglesias.
+ *
+ * Copyright (c) 2011 Calxeda, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "sysbus.h"
+#include "qemu-char.h"
+#include "qemu-log.h"
+#include "net.h"
+#include "net/checksum.h"
+
+#ifdef DEBUG_XGMAC
+#define DEBUGF_BRK(message, args...) do { \
+                                         fprintf(stderr, (message), ## args); \
+                                     } while (0)
+#else
+#define DEBUGF_BRK(message, args...) do { } while (0)
+#endif
+
+#define XGMAC_CONTROL           0x00000000   /* MAC Configuration */
+#define XGMAC_FRAME_FILTER      0x00000001   /* MAC Frame Filter */
+#define XGMAC_FLOW_CTRL         0x00000006   /* MAC Flow Control */
+#define XGMAC_VLAN_TAG          0x00000007   /* VLAN Tags */
+#define XGMAC_VERSION           0x00000008   /* Version */
+/* VLAN tag for insertion or replacement into tx frames */
+#define XGMAC_VLAN_INCL         0x00000009
+#define XGMAC_LPI_CTRL          0x0000000a   /* LPI Control and Status */
+#define XGMAC_LPI_TIMER         0x0000000b   /* LPI Timers Control */
+#define XGMAC_TX_PACE           0x0000000c   /* Transmit Pace and Stretch */
+#define XGMAC_VLAN_HASH         0x0000000d   /* VLAN Hash Table */
+#define XGMAC_DEBUG             0x0000000e   /* Debug */
+#define XGMAC_INT_STATUS        0x0000000f   /* Interrupt and Control */
+/* HASH table registers */
+#define XGMAC_HASH(n)           ((0x00000300/4) + (n))
+#define XGMAC_NUM_HASH          16
+/* Operation Mode */
+#define XGMAC_OPMODE            (0x00000400/4)
+/* Remote Wake-Up Frame Filter */
+#define XGMAC_REMOTE_WAKE       (0x00000700/4)
+/* PMT Control and Status */
+#define XGMAC_PMT               (0x00000704/4)
+
+#define XGMAC_ADDR_HIGH(reg)    (0x00000010+((reg) * 2))
+#define XGMAC_ADDR_LOW(reg)     (0x00000011+((reg) * 2))
+
+#define DMA_BUS_MODE            0x000003c0   /* Bus Mode */
+#define DMA_XMT_POLL_DEMAND     0x000003c1   /* Transmit Poll Demand */
+#define DMA_RCV_POLL_DEMAND     0x000003c2   /* Received Poll Demand */
+#define DMA_RCV_BASE_ADDR       0x000003c3   /* Receive List Base */
+#define DMA_TX_BASE_ADDR        0x000003c4   /* Transmit List Base */
+#define DMA_STATUS              0x000003c5   /* Status Register */
+#define DMA_CONTROL             0x000003c6   /* Ctrl (Operational Mode) */
+#define DMA_INTR_ENA            0x000003c7   /* Interrupt Enable */
+#define DMA_MISSED_FRAME_CTR    0x000003c8   /* Missed Frame Counter */
+/* Receive Interrupt Watchdog Timer */
+#define DMA_RI_WATCHDOG_TIMER   0x000003c9
+#define DMA_AXI_BUS             0x000003ca   /* AXI Bus Mode */
+#define DMA_AXI_STATUS          0x000003cb   /* AXI Status */
+#define DMA_CUR_TX_DESC_ADDR    0x000003d2   /* Current Host Tx Descriptor */
+#define DMA_CUR_RX_DESC_ADDR    0x000003d3   /* Current Host Rx Descriptor */
+#define DMA_CUR_TX_BUF_ADDR     0x000003d4   /* Current Host Tx Buffer */
+#define DMA_CUR_RX_BUF_ADDR     0x000003d5   /* Current Host Rx Buffer */
+#define DMA_HW_FEATURE          0x000003d6   /* Enabled Hardware Features */
+
+/* DMA Status register defines */
+#define DMA_STATUS_GMI          0x08000000   /* MMC interrupt */
+#define DMA_STATUS_GLI          0x04000000   /* GMAC Line interface int */
+#define DMA_STATUS_EB_MASK      0x00380000   /* Error Bits Mask */
+#define DMA_STATUS_EB_TX_ABORT  0x00080000   /* Error Bits - TX Abort */
+#define DMA_STATUS_EB_RX_ABORT  0x00100000   /* Error Bits - RX Abort */
+#define DMA_STATUS_TS_MASK      0x00700000   /* Transmit Process State */
+#define DMA_STATUS_TS_SHIFT     20
+#define DMA_STATUS_RS_MASK      0x000e0000   /* Receive Process State */
+#define DMA_STATUS_RS_SHIFT     17
+#define DMA_STATUS_NIS          0x00010000   /* Normal Interrupt Summary */
+#define DMA_STATUS_AIS          0x00008000   /* Abnormal Interrupt Summary */
+#define DMA_STATUS_ERI          0x00004000   /* Early Receive Interrupt */
+#define DMA_STATUS_FBI          0x00002000   /* Fatal Bus Error Interrupt */
+#define DMA_STATUS_ETI          0x00000400   /* Early Transmit Interrupt */
+#define DMA_STATUS_RWT          0x00000200   /* Receive Watchdog Timeout */
+#define DMA_STATUS_RPS          0x00000100   /* Receive Process Stopped */
+#define DMA_STATUS_RU           0x00000080   /* Receive Buffer Unavailable */
+#define DMA_STATUS_RI           0x00000040   /* Receive Interrupt */
+#define DMA_STATUS_UNF          0x00000020   /* Transmit Underflow */
+#define DMA_STATUS_OVF          0x00000010   /* Receive Overflow */
+#define DMA_STATUS_TJT          0x00000008   /* Transmit Jabber Timeout */
+#define DMA_STATUS_TU           0x00000004   /* Transmit Buffer Unavailable */
+#define DMA_STATUS_TPS          0x00000002   /* Transmit Process Stopped */
+#define DMA_STATUS_TI           0x00000001   /* Transmit Interrupt */
+
+/* DMA Control register defines */
+#define DMA_CONTROL_ST          0x00002000   /* Start/Stop Transmission */
+#define DMA_CONTROL_SR          0x00000002   /* Start/Stop Receive */
+#define DMA_CONTROL_DFF         0x01000000   /* Disable flush of rx frames */
+
+struct desc {
+    uint32_t ctl_stat;
+    uint16_t buffer1_size;
+    uint16_t buffer2_size;
+    uint32_t buffer1_addr;
+    uint32_t buffer2_addr;
+    uint32_t ext_stat;
+    uint32_t res[3];
+};
+
+#define R_MAX 0x400
+
+typedef struct rxtx_stats {
+    uint64_t rx_bytes;
+    uint64_t tx_bytes;
+
+    uint64_t rx;
+    uint64_t rx_bcast;
+    uint64_t rx_mcast;
+} rxtx_stats;
+
+typedef struct xgmac_state {
+    SysBusDevice busdev;
+    MemoryRegion iomem;
+    qemu_irq sbd_irq;
+    qemu_irq pmt_irq;
+    qemu_irq mci_irq;
+    NICState *nic;
+    NICConf conf;
+
+    uint32_t c_phyaddr;
+    struct rxtx_stats stats;
+    uint32_t regs[R_MAX];
+} xgmac_state;
+
+const VMStateDescription vmstate_rxtx_stats = {
+    .name = "xgmac_stats",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT64(rx_bytes, rxtx_stats),
+        VMSTATE_UINT64(tx_bytes, rxtx_stats),
+        VMSTATE_UINT64(rx, rxtx_stats),
+        VMSTATE_UINT64(rx_bcast, rxtx_stats),
+        VMSTATE_UINT64(rx_mcast, rxtx_stats),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_xgmac = {
+    .name = "xgmac",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(c_phyaddr, xgmac_state),
+        VMSTATE_STRUCT(stats, xgmac_state, 0, vmstate_rxtx_stats, rxtx_stats),
+        VMSTATE_UINT32_ARRAY(regs, xgmac_state, R_MAX),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void xgmac_read_desc(struct xgmac_state *s, struct desc *d, int rx)
+{
+    uint32_t addr = rx ? s->regs[DMA_CUR_RX_DESC_ADDR] :
+        s->regs[DMA_CUR_TX_DESC_ADDR];
+    cpu_physical_memory_read(addr, d, sizeof(*d));
+}
+
+static void xgmac_write_desc(struct xgmac_state *s, struct desc *d, int rx)
+{
+    int reg = rx ? DMA_CUR_RX_DESC_ADDR : DMA_CUR_TX_DESC_ADDR;
+    uint32_t addr = s->regs[reg];
+
+    if (!rx && (d->ctl_stat & 0x00200000)) {
+        s->regs[reg] = s->regs[DMA_TX_BASE_ADDR];
+    } else if (rx && (d->buffer1_size & 0x8000)) {
+        s->regs[reg] = s->regs[DMA_RCV_BASE_ADDR];
+    } else {
+        s->regs[reg] += sizeof(*d);
+    }
+    cpu_physical_memory_write(addr, d, sizeof(*d));
+}
+
+static void xgmac_enet_send(struct xgmac_state *s)
+{
+    struct desc bd;
+    int frame_size;
+    int len;
+    uint8_t frame[8192];
+    uint8_t *ptr;
+
+    ptr = frame;
+    frame_size = 0;
+    while (1) {
+        xgmac_read_desc(s, &bd, 0);
+        if ((bd.ctl_stat & 0x80000000) == 0) {
+            /* Run out of descriptors to transmit.  */
+            break;
+        }
+        len = (bd.buffer1_size & 0xfff) + (bd.buffer2_size & 0xfff);
+
+        if ((bd.buffer1_size & 0xfff) > 2048) {
+            DEBUGF_BRK("qemu:%s:ERROR...ERROR...ERROR... -- "
+                        "xgmac buffer 1 len on send > 2048 (0x%x)\n",
+                         __func__, bd.buffer1_size & 0xfff);
+        }
+        if ((bd.buffer2_size & 0xfff) != 0) {
+            DEBUGF_BRK("qemu:%s:ERROR...ERROR...ERROR... -- "
+                        "xgmac buffer 2 len on send != 0 (0x%x)\n",
+                        __func__, bd.buffer2_size & 0xfff);
+        }
+        if (len >= sizeof(frame)) {
+            DEBUGF_BRK("qemu:%s: buffer overflow %d read into %zu "
+                        "buffer\n" , __func__, len, sizeof(frame));
+            DEBUGF_BRK("qemu:%s: buffer1.size=%d; buffer2.size=%d\n",
+                        __func__, bd.buffer1_size, bd.buffer2_size);
+        }
+
+        cpu_physical_memory_read(bd.buffer1_addr, ptr, len);
+        ptr += len;
+        frame_size += len;
+        if (bd.ctl_stat & 0x20000000) {
+            /* Last buffer in frame.  */
+            qemu_send_packet(&s->nic->nc, frame, len);
+            ptr = frame;
+            frame_size = 0;
+            s->regs[DMA_STATUS] |= DMA_STATUS_TI | DMA_STATUS_NIS;
+        }
+        bd.ctl_stat &= ~0x80000000;
+        /* Write back the modified descriptor.  */
+        xgmac_write_desc(s, &bd, 0);
+    }
+}
+
+static void enet_update_irq(struct xgmac_state *s)
+{
+    int stat = s->regs[DMA_STATUS] & s->regs[DMA_INTR_ENA];
+    qemu_set_irq(s->sbd_irq, !!stat);
+}
+
+static uint64_t enet_read(void *opaque, target_phys_addr_t addr, unsigned size)
+{
+    struct xgmac_state *s = opaque;
+    uint64_t r = 0;
+    addr >>= 2;
+
+    switch (addr) {
+    case XGMAC_VERSION:
+        r = 0x1012;
+        break;
+    default:
+        if (addr < ARRAY_SIZE(s->regs)) {
+            r = s->regs[addr];
+        }
+        break;
+    }
+    return r;
+}
+
+static void enet_write(void *opaque, target_phys_addr_t addr,
+                       uint64_t value, unsigned size)
+{
+    struct xgmac_state *s = opaque;
+
+    addr >>= 2;
+    switch (addr) {
+    case DMA_BUS_MODE:
+        s->regs[DMA_BUS_MODE] = value & ~0x1;
+        break;
+    case DMA_XMT_POLL_DEMAND:
+        xgmac_enet_send(s);
+        break;
+    case DMA_STATUS:
+        s->regs[DMA_STATUS] = s->regs[DMA_STATUS] & ~value;
+        break;
+    case DMA_RCV_BASE_ADDR:
+        s->regs[DMA_RCV_BASE_ADDR] = s->regs[DMA_CUR_RX_DESC_ADDR] = value;
+        break;
+    case DMA_TX_BASE_ADDR:
+        s->regs[DMA_TX_BASE_ADDR] = s->regs[DMA_CUR_TX_DESC_ADDR] = value;
+        break;
+    default:
+        if (addr < ARRAY_SIZE(s->regs)) {
+            s->regs[addr] = value;
+        }
+        break;
+    }
+    enet_update_irq(s);
+}
+
+static const MemoryRegionOps enet_mem_ops = {
+    .read = enet_read,
+    .write = enet_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static int eth_can_rx(VLANClientState *nc)
+{
+    struct xgmac_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
+
+    /* RX enabled?  */
+    return s->regs[DMA_CONTROL] & DMA_CONTROL_SR;
+}
+
+static ssize_t eth_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
+{
+    struct xgmac_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
+    static const unsigned char sa_bcast[6] = {0xff, 0xff, 0xff,
+                                              0xff, 0xff, 0xff};
+    int unicast, broadcast, multicast;
+    struct desc bd;
+    ssize_t ret;
+
+    unicast = ~buf[0] & 0x1;
+    broadcast = memcmp(buf, sa_bcast, 6) == 0;
+    multicast = !unicast && !broadcast;
+    if (size < 12) {
+        s->regs[DMA_STATUS] |= DMA_STATUS_RI | DMA_STATUS_NIS;
+        ret = -1;
+        goto out;
+    }
+
+    xgmac_read_desc(s, &bd, 1);
+    if ((bd.ctl_stat & 0x80000000) == 0) {
+        s->regs[DMA_STATUS] |= DMA_STATUS_RU | DMA_STATUS_AIS;
+        ret = size;
+        goto out;
+    }
+
+    cpu_physical_memory_write(bd.buffer1_addr, buf, size);
+
+    /* Add in the 4 bytes for crc (the real hw returns length incl crc) */
+    size += 4;
+    bd.ctl_stat = (size << 16) | 0x300;
+    xgmac_write_desc(s, &bd, 1);
+
+    s->stats.rx_bytes += size;
+    s->stats.rx++;
+    if (multicast) {
+        s->stats.rx_mcast++;
+    } else if (broadcast) {
+        s->stats.rx_bcast++;
+    }
+
+    s->regs[DMA_STATUS] |= DMA_STATUS_RI | DMA_STATUS_NIS;
+    ret = size;
+
+out:
+    enet_update_irq(s);
+    return ret;
+}
+
+static void eth_cleanup(VLANClientState *nc)
+{
+    struct xgmac_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
+    s->nic = NULL;
+}
+
+static NetClientInfo net_xgmac_enet_info = {
+    .type = NET_CLIENT_TYPE_NIC,
+    .size = sizeof(NICState),
+    .can_receive = eth_can_rx,
+    .receive = eth_rx,
+    .cleanup = eth_cleanup,
+};
+
+static int xgmac_enet_init(SysBusDevice *dev)
+{
+    struct xgmac_state *s = FROM_SYSBUS(typeof(*s), dev);
+
+    memory_region_init_io(&s->iomem, &enet_mem_ops, s, "xgmac", 0x1000);
+    sysbus_init_mmio(dev, &s->iomem);
+    sysbus_init_irq(dev, &s->sbd_irq);
+    sysbus_init_irq(dev, &s->pmt_irq);
+    sysbus_init_irq(dev, &s->mci_irq);
+
+    qemu_macaddr_default_if_unset(&s->conf.macaddr);
+    s->nic = qemu_new_nic(&net_xgmac_enet_info, &s->conf,
+                          dev->qdev.info->name, dev->qdev.id, s);
+    qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
+
+    s->regs[XGMAC_ADDR_HIGH(0)] = (s->conf.macaddr.a[5] << 8) |
+                                   s->conf.macaddr.a[4];
+    s->regs[XGMAC_ADDR_LOW(0)] = (s->conf.macaddr.a[3] << 24) |
+                                 (s->conf.macaddr.a[2] << 16) |
+                                 (s->conf.macaddr.a[1] << 8) |
+                                  s->conf.macaddr.a[0];
+
+    return 0;
+}
+
+static SysBusDeviceInfo xgmac_enet_info = {
+    .init = xgmac_enet_init,
+    .qdev.name  = "xgmac",
+    .qdev.size  = sizeof(struct xgmac_state),
+    .qdev.vmsd = &vmstate_xgmac,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("phyaddr", struct xgmac_state, c_phyaddr, 7),
+        DEFINE_NIC_PROPERTIES(struct xgmac_state, conf),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+static void xgmac_enet_register(void)
+{
+    sysbus_register_withprop(&xgmac_enet_info);
+}
+
+device_init(xgmac_enet_register)
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [Qemu-devel] [PATCH v5 7/7] arm: make the number of GIC interrupts configurable
  2011-12-29 16:19 [Qemu-devel] [PATCH v5 0/7] various ARM fixes for Calxeda Highbank Mark Langsdorf
                   ` (5 preceding siblings ...)
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 6/7] Add xgmac ethernet model Mark Langsdorf
@ 2011-12-29 16:19 ` Mark Langsdorf
  6 siblings, 0 replies; 26+ messages in thread
From: Mark Langsdorf @ 2011-12-29 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Mark Langsdorf, afaerber, rob.herring

Increase the maximum number of GIC interrupts for a9mp and a11mp to 256,
and create a configurable property for each defaulting to 96 and 64
(respectively) so that device modelers can set the value appropriately
for their SoC. Other ARM processors also set their maximum number of
used IRQs appropriately.

Set the maximum theoretically number of GIC interrupts to 1020 and
update the save/restore code to only use the appropriate number for
each SoC.

Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
Changes from v4
	None
Changes from v3
        Increase maximum number of GIC interrupts to 1020
        Remove SoC/implementation specific GIC_NIRQ #defs
        Added properties code to arm11mp
        Changed error handling for too many interrupts
        Redid save/load handling
Changes from v2
        Skipped
Changes from v1
        Increase the number of a9mp interrupts to 192
        Add a property defaulting to 96
        Add a num_irq member in the gic state structure
        Use the num_irq value as appropriate
        Add num_irq argument to gic_init()
        Add num_irq to various CPU calls to gic_init

 hw/a9mpcore.c     |    7 +++--
 hw/arm11mpcore.c  |   14 +++++++-----
 hw/arm_gic.c      |   57 +++++++++++++++++++++++++++++-----------------------
 hw/armv7m_nvic.c  |    7 ++---
 hw/realview_gic.c |    3 +-
 5 files changed, 48 insertions(+), 40 deletions(-)

diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index 3ef0e13..8c8b72b 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -11,9 +11,8 @@
 #include "sysbus.h"
 
 /* Configuration for arm_gic.c:
- * number of external IRQ lines, max number of CPUs, how to ID current CPU
+ * max number of CPUs, how to ID current CPU
  */
-#define GIC_NIRQ 96
 #define NCPU 4
 
 static inline int
@@ -37,6 +36,7 @@ typedef struct a9mp_priv_state {
     MemoryRegion ptimer_iomem;
     MemoryRegion container;
     DeviceState *mptimer;
+    uint32_t num_irq;
 } a9mp_priv_state;
 
 static uint64_t a9_scu_read(void *opaque, target_phys_addr_t offset,
@@ -153,7 +153,7 @@ static int a9mp_priv_init(SysBusDevice *dev)
         hw_error("a9mp_priv_init: num-cpu may not be more than %d\n", NCPU);
     }
 
-    gic_init(&s->gic, s->num_cpu);
+    gic_init(&s->gic, s->num_cpu, s->num_irq);
 
     s->mptimer = qdev_create(NULL, "arm_mptimer");
     qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu);
@@ -216,6 +216,7 @@ static SysBusDeviceInfo a9mp_priv_info = {
     .qdev.reset = a9mp_priv_reset,
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT32("num-cpu", a9mp_priv_state, num_cpu, 1),
+        DEFINE_PROP_UINT32("num-irq", a9mp_priv_state, num_irq, 256),
         DEFINE_PROP_END_OF_LIST(),
     }
 };
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index bc0457e..e4e4bb3 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -10,11 +10,6 @@
 #include "sysbus.h"
 #include "qemu-timer.h"
 
-/* ??? The MPCore TRM says the on-chip controller has 224 external IRQ lines
-   (+ 32 internal).  However my test chip only exposes/reports 32.
-   More importantly Linux falls over if more than 32 are present!  */
-#define GIC_NIRQ 64
-
 #define NCPU 4
 
 static inline int
@@ -37,6 +32,7 @@ typedef struct mpcore_priv_state {
     MemoryRegion iomem;
     MemoryRegion container;
     DeviceState *mptimer;
+    uint32_t num_irq;
 } mpcore_priv_state;
 
 /* Per-CPU private memory mapped IO.  */
@@ -132,7 +128,7 @@ static int mpcore_priv_init(SysBusDevice *dev)
 {
     mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev);
 
-    gic_init(&s->gic, s->num_cpu);
+    gic_init(&s->gic, s->num_cpu, GIC_NIRQ);
     s->mptimer = qdev_create(NULL, "arm_mptimer");
     qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu);
     qdev_init_nofail(s->mptimer);
@@ -221,6 +217,12 @@ static SysBusDeviceInfo mpcore_priv_info = {
     .qdev.size  = sizeof(mpcore_priv_state),
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT32("num-cpu", mpcore_priv_state, num_cpu, 1),
+        /* The MPCore TRM says the on-chip controller has 224 external
+         * IRQ lines (+ 32 internal).  Some test chips only
+         * expose/report 32. More importantly Linux falls over if more
+         * than 32 are present!  Set the default to 64 and let chips
+         * with more working lines set it higher */
+        DEFINE_PROP_UINT32("num-irq", mpcore_priv_state, num_irq, 64),
         DEFINE_PROP_END_OF_LIST(),
     }
 };
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 0339cf5..5bfb01f 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -11,6 +11,7 @@
    controller, MPCore distributed interrupt controller and ARMv7-M
    Nested Vectored Interrupt Controller.  */
 
+#define GIC_NIRQ 1020
 //#define DEBUG_GIC
 
 #ifdef DEBUG_GIC
@@ -111,6 +112,7 @@ typedef struct gic_state
     struct gic_state *backref[NCPU];
     MemoryRegion cpuiomem[NCPU+1]; /* CPU interfaces */
 #endif
+    int num_irq;
 } gic_state;
 
 /* TODO: Many places that call this routine could be optimized.  */
@@ -133,7 +135,7 @@ static void gic_update(gic_state *s)
         }
         best_prio = 0x100;
         best_irq = 1023;
-        for (irq = 0; irq < GIC_NIRQ; irq++) {
+        for (irq = 0; irq < s->num_irq; irq++) {
             if (GIC_TEST_ENABLED(irq, cm) && GIC_TEST_PENDING(irq, cm)) {
                 if (GIC_GET_PRIORITY(irq, cpu) < best_prio) {
                     best_prio = GIC_GET_PRIORITY(irq, cpu);
@@ -222,7 +224,7 @@ static void gic_complete_irq(gic_state * s, int cpu, int irq)
     int update = 0;
     int cm = 1 << cpu;
     DPRINTF("EOI %d\n", irq);
-    if (irq >= GIC_NIRQ) {
+    if (irq >= s->num_irq) {
         /* This handles two cases:
          * 1. If software writes the ID of a spurious interrupt [ie 1023]
          * to the GICC_EOIR, the GIC ignores that write.
@@ -279,7 +281,7 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
         if (offset == 0)
             return s->enabled;
         if (offset == 4)
-            return ((GIC_NIRQ / 32) - 1) | ((NUM_CPU(s) - 1) << 5);
+            return ((s->num_irq / 32) - 1) | ((NUM_CPU(s) - 1) << 5);
         if (offset < 0x08)
             return 0;
         if (offset >= 0x80) {
@@ -295,7 +297,7 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
         else
             irq = (offset - 0x180) * 8;
         irq += GIC_BASE_IRQ;
-        if (irq >= GIC_NIRQ)
+        if (irq >= s->num_irq)
             goto bad_reg;
         res = 0;
         for (i = 0; i < 8; i++) {
@@ -310,7 +312,7 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
         else
             irq = (offset - 0x280) * 8;
         irq += GIC_BASE_IRQ;
-        if (irq >= GIC_NIRQ)
+        if (irq >= s->num_irq)
             goto bad_reg;
         res = 0;
         mask = (irq < 32) ?  cm : ALL_CPU_MASK;
@@ -322,7 +324,7 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
     } else if (offset < 0x400) {
         /* Interrupt Active.  */
         irq = (offset - 0x300) * 8 + GIC_BASE_IRQ;
-        if (irq >= GIC_NIRQ)
+        if (irq >= s->num_irq)
             goto bad_reg;
         res = 0;
         mask = (irq < 32) ?  cm : ALL_CPU_MASK;
@@ -334,14 +336,14 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
     } else if (offset < 0x800) {
         /* Interrupt Priority.  */
         irq = (offset - 0x400) + GIC_BASE_IRQ;
-        if (irq >= GIC_NIRQ)
+        if (irq >= s->num_irq)
             goto bad_reg;
         res = GIC_GET_PRIORITY(irq, cpu);
 #ifndef NVIC
     } else if (offset < 0xc00) {
         /* Interrupt CPU Target.  */
         irq = (offset - 0x800) + GIC_BASE_IRQ;
-        if (irq >= GIC_NIRQ)
+        if (irq >= s->num_irq)
             goto bad_reg;
         if (irq >= 29 && irq <= 31) {
             res = cm;
@@ -351,7 +353,7 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
     } else if (offset < 0xf00) {
         /* Interrupt Configuration.  */
         irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ;
-        if (irq >= GIC_NIRQ)
+        if (irq >= s->num_irq)
             goto bad_reg;
         res = 0;
         for (i = 0; i < 4; i++) {
@@ -426,7 +428,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
     } else if (offset < 0x180) {
         /* Interrupt Set Enable.  */
         irq = (offset - 0x100) * 8 + GIC_BASE_IRQ;
-        if (irq >= GIC_NIRQ)
+        if (irq >= s->num_irq)
             goto bad_reg;
         if (irq < 16)
           value = 0xff;
@@ -451,7 +453,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
     } else if (offset < 0x200) {
         /* Interrupt Clear Enable.  */
         irq = (offset - 0x180) * 8 + GIC_BASE_IRQ;
-        if (irq >= GIC_NIRQ)
+        if (irq >= s->num_irq)
             goto bad_reg;
         if (irq < 16)
           value = 0;
@@ -468,7 +470,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
     } else if (offset < 0x280) {
         /* Interrupt Set Pending.  */
         irq = (offset - 0x200) * 8 + GIC_BASE_IRQ;
-        if (irq >= GIC_NIRQ)
+        if (irq >= s->num_irq)
             goto bad_reg;
         if (irq < 16)
           irq = 0;
@@ -481,7 +483,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
     } else if (offset < 0x300) {
         /* Interrupt Clear Pending.  */
         irq = (offset - 0x280) * 8 + GIC_BASE_IRQ;
-        if (irq >= GIC_NIRQ)
+        if (irq >= s->num_irq)
             goto bad_reg;
         for (i = 0; i < 8; i++) {
             /* ??? This currently clears the pending bit for all CPUs, even
@@ -497,7 +499,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
     } else if (offset < 0x800) {
         /* Interrupt Priority.  */
         irq = (offset - 0x400) + GIC_BASE_IRQ;
-        if (irq >= GIC_NIRQ)
+        if (irq >= s->num_irq)
             goto bad_reg;
         if (irq < 32) {
             s->priority1[irq][cpu] = value;
@@ -508,7 +510,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
     } else if (offset < 0xc00) {
         /* Interrupt CPU Target.  */
         irq = (offset - 0x800) + GIC_BASE_IRQ;
-        if (irq >= GIC_NIRQ)
+        if (irq >= s->num_irq)
             goto bad_reg;
         if (irq < 29)
             value = 0;
@@ -518,7 +520,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
     } else if (offset < 0xf00) {
         /* Interrupt Configuration.  */
         irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
-        if (irq >= GIC_NIRQ)
+        if (irq >= s->num_irq)
             goto bad_reg;
         if (irq < 32)
             value |= 0xaa;
@@ -735,17 +737,17 @@ static void gic_save(QEMUFile *f, void *opaque)
         qemu_put_be32(f, s->cpu_enabled[i]);
         for (j = 0; j < 32; j++)
             qemu_put_be32(f, s->priority1[j][i]);
-        for (j = 0; j < GIC_NIRQ; j++)
+        for (j = 0; j < s->num_irq; j++)
             qemu_put_be32(f, s->last_active[j][i]);
         qemu_put_be32(f, s->priority_mask[i]);
         qemu_put_be32(f, s->running_irq[i]);
         qemu_put_be32(f, s->running_priority[i]);
         qemu_put_be32(f, s->current_pending[i]);
     }
-    for (i = 0; i < GIC_NIRQ - 32; i++) {
+    for (i = 0; i < s->num_irq - 32; i++) {
         qemu_put_be32(f, s->priority2[i]);
     }
-    for (i = 0; i < GIC_NIRQ; i++) {
+    for (i = 0; i < s->num_irq; i++) {
 #ifndef NVIC
         qemu_put_be32(f, s->irq_target[i]);
 #endif
@@ -772,17 +774,17 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id)
         s->cpu_enabled[i] = qemu_get_be32(f);
         for (j = 0; j < 32; j++)
             s->priority1[j][i] = qemu_get_be32(f);
-        for (j = 0; j < GIC_NIRQ; j++)
+        for (j = 0; j < s->num_irq; j++)
             s->last_active[j][i] = qemu_get_be32(f);
         s->priority_mask[i] = qemu_get_be32(f);
         s->running_irq[i] = qemu_get_be32(f);
         s->running_priority[i] = qemu_get_be32(f);
         s->current_pending[i] = qemu_get_be32(f);
     }
-    for (i = 0; i < GIC_NIRQ - 32; i++) {
+    for (i = 0; i < s->num_irq - 32; i++) {
         s->priority2[i] = qemu_get_be32(f);
     }
-    for (i = 0; i < GIC_NIRQ; i++) {
+    for (i = 0; i < s->num_irq; i++) {
 #ifndef NVIC
         s->irq_target[i] = qemu_get_be32(f);
 #endif
@@ -798,9 +800,9 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id)
 }
 
 #if NCPU > 1
-static void gic_init(gic_state *s, int num_cpu)
+static void gic_init(gic_state *s, int num_cpu, int num_irq)
 #else
-static void gic_init(gic_state *s)
+static void gic_init(gic_state *s, int num_irq)
 #endif
 {
     int i;
@@ -808,7 +810,12 @@ static void gic_init(gic_state *s)
 #if NCPU > 1
     s->num_cpu = num_cpu;
 #endif
-    qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, GIC_NIRQ - 32);
+    s->num_irq = num_irq;
+    if (s->num_irq > GIC_NIRQ) {
+        hw_error("device requested %u out of %u interrupt lines, failing\n",
+                 num_irq, GIC_NIRQ);
+    }
+    qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, s->num_irq - 32);
     for (i = 0; i < NUM_CPU(s); i++) {
         sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
     }
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index bf8c3c5..0de51f4 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -15,9 +15,6 @@
 #include "arm-misc.h"
 #include "exec-memory.h"
 
-/* 32 internal lines (16 used for system exceptions) plus 64 external
-   interrupt lines.  */
-#define GIC_NIRQ 96
 #define NCPU 1
 #define NVIC 1
 
@@ -384,7 +381,9 @@ static int armv7m_nvic_init(SysBusDevice *dev)
 {
     nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev);
 
-    gic_init(&s->gic);
+   /* 32 internal lines (16 used for system exceptions) plus 64 external
+    * interrupt lines.  */
+    gic_init(&s->gic, 96);
     memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->gic.iomem);
     s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s);
     vmstate_register(&dev->qdev, -1, &vmstate_nvic, s);
diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index 8c4d509..cd7e53d 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -9,7 +9,6 @@
 
 #include "sysbus.h"
 
-#define GIC_NIRQ 96
 #define NCPU 1
 
 /* Only a single "CPU" interface is present.  */
@@ -37,7 +36,7 @@ static int realview_gic_init(SysBusDevice *dev)
 {
     RealViewGICState *s = FROM_SYSBUSGIC(RealViewGICState, dev);
 
-    gic_init(&s->gic);
+    gic_init(&s->gic, 96);
     realview_gic_map_setup(s);
     sysbus_init_mmio(dev, &s->container);
     return 0;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] [PATCH v5 5/5] add L2x0/PL310 cache controller device
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 5/5] add L2x0/PL310 cache controller device Mark Langsdorf
@ 2012-01-04 13:29   ` Peter Maydell
  2012-06-07 13:45   ` Andreas Färber
  1 sibling, 0 replies; 26+ messages in thread
From: Peter Maydell @ 2012-01-04 13:29 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: qemu-devel, rob.herring, afaerber

On 29 December 2011 16:19, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> This is just a dummy device for ARM L2 cache controllers, based on the
> pl310. The cache type parameter can be defined by a property value
> and has a meaningful default.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

(well, it has a stray blank line at the end, but I'll just zap that when I put
it into arm-devs.next.)

I'll put together the simple patches that add the cache controller to vexpress
and realview shortly.

-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] [PATCH v5 3/7] arm: add dummy v7 cp15 config_base_register
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 3/7] arm: add dummy v7 cp15 config_base_register Mark Langsdorf
@ 2012-01-04 14:32   ` Peter Maydell
  2012-01-04 16:32     ` Mark Langsdorf
  0 siblings, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2012-01-04 14:32 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: qemu-devel, rob.herring, afaerber

On 29 December 2011 16:19, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> Add a cp15 config_base_register that currently defaults to 0.
> After the QOM CPU support is added, the value will be properly
> set to the periphal base value.
>
> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

I need to revoke this Reviewed-by: because...

> @@ -2111,6 +2111,20 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
>              * 0x200 << ($rn & 0xfff), when MMU is off.  */
>             goto bad_reg;
>         }
> +        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
> +            switch (crm) {
> +            case 0:
> +                /* The config_base_address should hold the value of
> +                 * the peripheral base. ARM should get this from a CPU
> +                 * object property, but that support isn't available in
> +                 * December 2011. Default to 0 for now and board models
> +                 * that care can set it by a private hook */
> +                if ((op1 == 4) && (op2 == 0)) {
> +                    return env->cp15.c15_config_base_address;
> +                }
> +            }
> +            goto bad_reg;
> +        }
>         return 0;

this breaks booting on vexpress, which complains
qemu: fatal: Unimplemented cp15 register read (c15, c0, {0, 1})
because we're now barfing on all the other c15 registers which we
used to read as zero.

The simplest fix is to drop that 'goto bad_reg;'.
More complicatedly we could decode the c15 range properly for A9
(as per the TRM).

-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] [PATCH v5 3/7] arm: add dummy v7 cp15 config_base_register
  2012-01-04 14:32   ` Peter Maydell
@ 2012-01-04 16:32     ` Mark Langsdorf
  2012-01-04 16:47       ` Peter Maydell
  0 siblings, 1 reply; 26+ messages in thread
From: Mark Langsdorf @ 2012-01-04 16:32 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel@nongnu.org, Rob Herring, afaerber@suse.de

On 01/04/2012 08:32 AM, Peter Maydell wrote:
> On 29 December 2011 16:19, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
>> Add a cp15 config_base_register that currently defaults to 0.
>> After the QOM CPU support is added, the value will be properly
>> set to the periphal base value.
>>
>> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
>> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> 
> I need to revoke this Reviewed-by: because...
> 
>> @@ -2111,6 +2111,20 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
>>              * 0x200 << ($rn & 0xfff), when MMU is off.  */
>>             goto bad_reg;
>>         }
>> +        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
>> +            switch (crm) {
>> +            case 0:
>> +                /* The config_base_address should hold the value of
>> +                 * the peripheral base. ARM should get this from a CPU
>> +                 * object property, but that support isn't available in
>> +                 * December 2011. Default to 0 for now and board models
>> +                 * that care can set it by a private hook */
>> +                if ((op1 == 4) && (op2 == 0)) {
>> +                    return env->cp15.c15_config_base_address;
>> +                }
>> +            }
>> +            goto bad_reg;
>> +        }
>>         return 0;
> 
> this breaks booting on vexpress, which complains
> qemu: fatal: Unimplemented cp15 register read (c15, c0, {0, 1})
> because we're now barfing on all the other c15 registers which we
> used to read as zero.

Fair enough. Can I just resubmit this one patch or do you want
the entire series?

--Mark Langsdorf
Calxeda, Inc.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] [PATCH v5 3/7] arm: add dummy v7 cp15 config_base_register
  2012-01-04 16:32     ` Mark Langsdorf
@ 2012-01-04 16:47       ` Peter Maydell
  2012-01-04 16:53         ` [Qemu-devel] [PATCH v6 1/1] arm: add dummy v7 cp15 registers Mark Langsdorf
  0 siblings, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2012-01-04 16:47 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: qemu-devel@nongnu.org, Rob Herring, afaerber@suse.de

On 4 January 2012 16:32, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> On 01/04/2012 08:32 AM, Peter Maydell wrote:
>> On 29 December 2011 16:19, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
>>> Add a cp15 config_base_register that currently defaults to 0.
>>> After the QOM CPU support is added, the value will be properly
>>> set to the periphal base value.
>>>
>>> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
>>> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
>>
>> I need to revoke this Reviewed-by: because...
>>
>>> @@ -2111,6 +2111,20 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
>>>              * 0x200 << ($rn & 0xfff), when MMU is off.  */
>>>             goto bad_reg;
>>>         }
>>> +        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
>>> +            switch (crm) {
>>> +            case 0:
>>> +                /* The config_base_address should hold the value of
>>> +                 * the peripheral base. ARM should get this from a CPU
>>> +                 * object property, but that support isn't available in
>>> +                 * December 2011. Default to 0 for now and board models
>>> +                 * that care can set it by a private hook */
>>> +                if ((op1 == 4) && (op2 == 0)) {
>>> +                    return env->cp15.c15_config_base_address;
>>> +                }
>>> +            }
>>> +            goto bad_reg;
>>> +        }
>>>         return 0;
>>
>> this breaks booting on vexpress, which complains
>> qemu: fatal: Unimplemented cp15 register read (c15, c0, {0, 1})
>> because we're now barfing on all the other c15 registers which we
>> used to read as zero.
>
> Fair enough. Can I just resubmit this one patch or do you want
> the entire series?

Just resubmit this one as a single patch -- it has to go through my target-arm
tree rather than arm-devs anyway so if you resent the series I'd just have
to break it apart. (As you may have noticed I've put some of the other
patches into an arm-devs pullreq.)

-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [Qemu-devel] [PATCH v6 1/1] arm: add dummy v7 cp15 registers
  2012-01-04 16:47       ` Peter Maydell
@ 2012-01-04 16:53         ` Mark Langsdorf
  2012-01-04 17:50           ` Peter Maydell
  0 siblings, 1 reply; 26+ messages in thread
From: Mark Langsdorf @ 2012-01-04 16:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, afaerber, Mark Langsdorf

Add dummy register support for the cp15, CRn=c15 registers.
config_base_register and power_control_register currently
default to 0, but may have improved support after the QOM
CPU patches are finished.

Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
Changes from v5
	Added handling for all c15 registers
Changes from v3, v4
        None
Changes from v2
        Added test against op2 
Changes from v1
        renamed the register
        added comments about how it will change when QOM CPUs are added

 target-arm/cpu.h    |    2 ++
 target-arm/helper.c |   30 ++++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c4d742f..f8fb558 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -149,6 +149,8 @@ typedef struct CPUARMState {
         uint32_t c15_i_max; /* Maximum D-cache dirty line index.  */
         uint32_t c15_i_min; /* Minimum D-cache dirty line index.  */
         uint32_t c15_threadid; /* TI debugger thread-ID.  */
+        uint32_t c15_config_base_address; /* SCU base address.  */
+        uint32_t c15_power_control; /* power control */
     } cp15;
 
     struct {
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 65f4fbf..f39bcf3 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2111,6 +2111,36 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
              * 0x200 << ($rn & 0xfff), when MMU is off.  */
             goto bad_reg;
         }
+        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
+            switch (crm) {
+            case 0:
+                if ((op1 == 4) && (op2 == 0)) {
+                /* The config_base_address should hold the value of
+                 * the peripheral base. ARM should get this from a CPU
+                 * object property, but that support isn't available in
+                 * December 2011. Default to 0 for now and board models
+                 * that care can set it by a private hook */
+                    return env->cp15.c15_config_base_address;
+                } else if ((op1 == 0) && (op2 == 0)) {
+                /* power_control should be set to maximum latency. Again,
+                   default to 0 and set by private hook */
+                    return env->cp15.c15_power_control;
+                }
+                break;
+            case 1: /* NEON Busy */
+                return 0;
+            case 5: /* tlb lockdown */
+            case 6:
+            case 7:
+                if ((op1 == 5) && (op2 == 2)) {
+                    return 0;
+                }
+                break;
+            default:
+                break;
+            }
+            goto bad_reg;
+        }
         return 0;
     }
 bad_reg:
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] [PATCH v6 1/1] arm: add dummy v7 cp15 registers
  2012-01-04 16:53         ` [Qemu-devel] [PATCH v6 1/1] arm: add dummy v7 cp15 registers Mark Langsdorf
@ 2012-01-04 17:50           ` Peter Maydell
  2012-01-04 18:23             ` Mark Langsdorf
  2012-01-04 19:07             ` [Qemu-devel] [PATCH v7] " Mark Langsdorf
  0 siblings, 2 replies; 26+ messages in thread
From: Peter Maydell @ 2012-01-04 17:50 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: qemu-devel, afaerber

On 4 January 2012 16:53, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> +        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
> +            switch (crm) {
> +            case 0:
> +                if ((op1 == 4) && (op2 == 0)) {
> +                /* The config_base_address should hold the value of
> +                 * the peripheral base. ARM should get this from a CPU
> +                 * object property, but that support isn't available in
> +                 * December 2011. Default to 0 for now and board models
> +                 * that care can set it by a private hook */
> +                    return env->cp15.c15_config_base_address;
> +                } else if ((op1 == 0) && (op2 == 0)) {
> +                /* power_control should be set to maximum latency. Again,
> +                   default to 0 and set by private hook */
> +                    return env->cp15.c15_power_control;
> +                }

This one's read-write, which means it needs (a) support in set_cp15
(b) save/load
support.

> +                break;
> +            case 1: /* NEON Busy */
> +                return 0;
> +            case 5: /* tlb lockdown */
> +            case 6:
> +            case 7:
> +                if ((op1 == 5) && (op2 == 2)) {
> +                    return 0;
> +                }
> +                break;
> +            default:
> +                break;
> +            }
> +            goto bad_reg;
> +        }

You also need to implement the diagnostic register c15,c0,0,1
otherwise Linux won't boot when it tries to run this code:
 http://lxr.linux.no/#linux+v3.1.7/arch/arm/mm/proc-v7.S#L345
I suggest that should be implemented as reads-as-written. (Again, will
need save/load
support.) Ditto for the power diagnostic control register c15,c0,0,2, as used in
this patch: http://www.spinics.net/lists/arm-kernel/msg115817.html

-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] [PATCH v6 1/1] arm: add dummy v7 cp15 registers
  2012-01-04 17:50           ` Peter Maydell
@ 2012-01-04 18:23             ` Mark Langsdorf
  2012-01-04 19:07             ` [Qemu-devel] [PATCH v7] " Mark Langsdorf
  1 sibling, 0 replies; 26+ messages in thread
From: Mark Langsdorf @ 2012-01-04 18:23 UTC (permalink / raw)
  To: qemu-devel

On 01/04/2012 11:50 AM, Peter Maydell wrote:
> On 4 January 2012 16:53, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
>> +                } else if ((op1 == 0) && (op2 == 0)) {
>> +                /* power_control should be set to maximum latency. Again,
>> +                   default to 0 and set by private hook */
>> +                    return env->cp15.c15_power_control;
>> +                }
> 
> This one's read-write, which means it needs (a) support in set_cp15
> (b) save/load support.

Okay.

> You also need to implement the diagnostic register c15,c0,0,1
> otherwise Linux won't boot when it tries to run this code:
>  http://lxr.linux.no/#linux+v3.1.7/arch/arm/mm/proc-v7.S#L345
> I suggest that should be implemented as reads-as-written. (Again, will
> need save/load
> support.) Ditto for the power diagnostic control register c15,c0,0,2, as used in
> this patch: http://www.spinics.net/lists/arm-kernel/msg115817.html

I'm handling all the c15 registers listed on p 4-11 of the Cortex-A9
r3p0 TRM. Would you please give me a reference for these other two
registers? I'm not seeing them. Thanks.

--Mark

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [Qemu-devel] [PATCH v7] arm: add dummy v7 cp15 registers
  2012-01-04 17:50           ` Peter Maydell
  2012-01-04 18:23             ` Mark Langsdorf
@ 2012-01-04 19:07             ` Mark Langsdorf
  2012-01-04 23:50               ` Peter Maydell
  1 sibling, 1 reply; 26+ messages in thread
From: Mark Langsdorf @ 2012-01-04 19:07 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, afaerber, Mark Langsdorf

Add dummy register support for the cp15, CRn=c15 registers.
config_base_register and power_control_register currently
default to 0, but may have improved support after the QOM
CPU patches are finished.

Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
Changes from v6
	Added the diagnostic registers
	Added save/load support
Changes from v5
        Added handling for all c15 registers
Changes from v3, v4
        None
Changes from v2
        Added test against op2 
Changes from v1
        renamed the config_base_register
        added comments about how it will change when QOM CPUs are added

 target-arm/cpu.h     |    4 ++++
 target-arm/helper.c  |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 target-arm/machine.c |    7 +++++++
 3 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c4d742f..3bc90e6 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -149,6 +149,10 @@ typedef struct CPUARMState {
         uint32_t c15_i_max; /* Maximum D-cache dirty line index.  */
         uint32_t c15_i_min; /* Minimum D-cache dirty line index.  */
         uint32_t c15_threadid; /* TI debugger thread-ID.  */
+        uint32_t c15_config_base_address; /* SCU base address.  */
+        uint32_t c15_diagnostic; /* diagnostic register */
+        uint32_t c15_power_diagnostic;
+        uint32_t c15_power_control; /* power control */
     } cp15;
 
     struct {
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 65f4fbf..62028e5 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1768,6 +1768,20 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
                 goto bad_reg;
             }
         }
+        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
+            switch (crm) {
+            case 0:
+                if ((op1 == 0) && (op2 == 0)) {
+                    env->cp15.c15_power_control = val;
+                } else if ((op1 == 0) && (op2 == 1)) {
+                    env->cp15.c15_diagnostic = val;
+                } else if ((op1 == 0) && (op2 == 2)) {
+                    env->cp15.c15_power_diagnostic = val;
+                }
+            default:
+                break;
+            }
+        }
         break;
     }
     return;
@@ -2111,6 +2125,40 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
              * 0x200 << ($rn & 0xfff), when MMU is off.  */
             goto bad_reg;
         }
+        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
+            switch (crm) {
+            case 0:
+                if ((op1 == 4) && (op2 == 0)) {
+                /* The config_base_address should hold the value of
+                 * the peripheral base. ARM should get this from a CPU
+                 * object property, but that support isn't available in
+                 * December 2011. Default to 0 for now and board models
+                 * that care can set it by a private hook */
+                    return env->cp15.c15_config_base_address;
+                } else if ((op1 == 0) && (op2 == 0)) {
+                /* power_control should be set to maximum latency. Again,
+                   default to 0 and set by private hook */
+                    return env->cp15.c15_power_control;
+                } else if ((op1 == 0) && (op2 == 1)) {
+                    return env->cp15.c15_diagnostic;
+                } else if ((op1 == 0) && (op2 == 2)) {
+                    return env->cp15.c15_power_diagnostic;
+                }
+                break;
+            case 1: /* NEON Busy */
+                return 0;
+            case 5: /* tlb lockdown */
+            case 6:
+            case 7:
+                if ((op1 == 5) && (op2 == 2)) {
+                    return 0;
+                }
+                break;
+            default:
+                break;
+            }
+            goto bad_reg;
+        }
         return 0;
     }
 bad_reg:
diff --git a/target-arm/machine.c b/target-arm/machine.c
index aaee9b9..7f25b0f 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -56,6 +56,9 @@ void cpu_save(QEMUFile *f, void *opaque)
     qemu_put_be32(f, env->cp15.c13_tls2);
     qemu_put_be32(f, env->cp15.c13_tls3);
     qemu_put_be32(f, env->cp15.c15_cpar);
+    qemu_put_be32(f, env->cp15.c15_power_control);
+    qemu_put_be32(f, env->cp15.c15_diagnostic);
+    qemu_put_be32(f, env->cp15.c15_power_diagnostic);
 
     qemu_put_be32(f, env->features);
 
@@ -170,6 +173,10 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     env->cp15.c13_tls2 = qemu_get_be32(f);
     env->cp15.c13_tls3 = qemu_get_be32(f);
     env->cp15.c15_cpar = qemu_get_be32(f);
+    env->cp15.c15_power_control = qemu_get_be32(f);
+    env->cp15.c15_diagnostic = qemu_get_be32(f);
+    env->cp15.c15_power_diagnostic = qemu_get_be32(f);
+
 
     env->features = qemu_get_be32(f);
 
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] [PATCH v7] arm: add dummy v7 cp15 registers
  2012-01-04 19:07             ` [Qemu-devel] [PATCH v7] " Mark Langsdorf
@ 2012-01-04 23:50               ` Peter Maydell
  2012-01-05  0:14                 ` [Qemu-devel] [PATCH v8] " Mark Langsdorf
  0 siblings, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2012-01-04 23:50 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: qemu-devel, afaerber

On 4 January 2012 19:07, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> Add dummy register support for the cp15, CRn=c15 registers.
> config_base_register and power_control_register currently
> default to 0, but may have improved support after the QOM
> CPU patches are finished.
>
> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
> ---
> Changes from v6
>        Added the diagnostic registers
>        Added save/load support
> Changes from v5
>        Added handling for all c15 registers
> Changes from v3, v4
>        None
> Changes from v2
>        Added test against op2
> Changes from v1
>        renamed the config_base_register
>        added comments about how it will change when QOM CPUs are added
>
>  target-arm/cpu.h     |    4 ++++
>  target-arm/helper.c  |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
>  target-arm/machine.c |    7 +++++++
>  3 files changed, 59 insertions(+), 0 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index c4d742f..3bc90e6 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -149,6 +149,10 @@ typedef struct CPUARMState {
>         uint32_t c15_i_max; /* Maximum D-cache dirty line index.  */
>         uint32_t c15_i_min; /* Minimum D-cache dirty line index.  */
>         uint32_t c15_threadid; /* TI debugger thread-ID.  */
> +        uint32_t c15_config_base_address; /* SCU base address.  */
> +        uint32_t c15_diagnostic; /* diagnostic register */
> +        uint32_t c15_power_diagnostic;
> +        uint32_t c15_power_control; /* power control */
>     } cp15;
>
>     struct {
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 65f4fbf..62028e5 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1768,6 +1768,20 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
>                 goto bad_reg;
>             }
>         }
> +        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
> +            switch (crm) {
> +            case 0:
> +                if ((op1 == 0) && (op2 == 0)) {
> +                    env->cp15.c15_power_control = val;
> +                } else if ((op1 == 0) && (op2 == 1)) {
> +                    env->cp15.c15_diagnostic = val;
> +                } else if ((op1 == 0) && (op2 == 2)) {
> +                    env->cp15.c15_power_diagnostic = val;
> +                }
> +            default:
> +                break;
> +            }
> +        }
>         break;
>     }
>     return;
> @@ -2111,6 +2125,40 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
>              * 0x200 << ($rn & 0xfff), when MMU is off.  */
>             goto bad_reg;
>         }
> +        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
> +            switch (crm) {
> +            case 0:
> +                if ((op1 == 4) && (op2 == 0)) {
> +                /* The config_base_address should hold the value of

The indentation's wrong here and below (checkpatch complains).

> +                 * the peripheral base. ARM should get this from a CPU
> +                 * object property, but that support isn't available in
> +                 * December 2011. Default to 0 for now and board models
> +                 * that care can set it by a private hook */
> +                    return env->cp15.c15_config_base_address;
> +                } else if ((op1 == 0) && (op2 == 0)) {
> +                /* power_control should be set to maximum latency. Again,
> +                   default to 0 and set by private hook */
> +                    return env->cp15.c15_power_control;
> +                } else if ((op1 == 0) && (op2 == 1)) {
> +                    return env->cp15.c15_diagnostic;
> +                } else if ((op1 == 0) && (op2 == 2)) {
> +                    return env->cp15.c15_power_diagnostic;
> +                }
> +                break;
> +            case 1: /* NEON Busy */
> +                return 0;
> +            case 5: /* tlb lockdown */
> +            case 6:
> +            case 7:
> +                if ((op1 == 5) && (op2 == 2)) {
> +                    return 0;
> +                }
> +                break;
> +            default:
> +                break;
> +            }
> +            goto bad_reg;
> +        }
>         return 0;
>     }
>  bad_reg:
> diff --git a/target-arm/machine.c b/target-arm/machine.c
> index aaee9b9..7f25b0f 100644
> --- a/target-arm/machine.c
> +++ b/target-arm/machine.c
> @@ -56,6 +56,9 @@ void cpu_save(QEMUFile *f, void *opaque)
>     qemu_put_be32(f, env->cp15.c13_tls2);
>     qemu_put_be32(f, env->cp15.c13_tls3);
>     qemu_put_be32(f, env->cp15.c15_cpar);
> +    qemu_put_be32(f, env->cp15.c15_power_control);
> +    qemu_put_be32(f, env->cp15.c15_diagnostic);
> +    qemu_put_be32(f, env->cp15.c15_power_diagnostic);
>
>     qemu_put_be32(f, env->features);
>
> @@ -170,6 +173,10 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
>     env->cp15.c13_tls2 = qemu_get_be32(f);
>     env->cp15.c13_tls3 = qemu_get_be32(f);
>     env->cp15.c15_cpar = qemu_get_be32(f);
> +    env->cp15.c15_power_control = qemu_get_be32(f);
> +    env->cp15.c15_diagnostic = qemu_get_be32(f);
> +    env->cp15.c15_power_diagnostic = qemu_get_be32(f);
> +

Stray blank line.

Adding fields to the cpu_load/cpu_save functions means you have
to bump CPU_SAVE_VERSION in target-arm/cpu.h.

>     env->features = qemu_get_be32(f);

Thanks for your efforts revising this patch; I think we're nearly there...

-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [Qemu-devel] [PATCH v8] arm: add dummy v7 cp15 registers
  2012-01-04 23:50               ` Peter Maydell
@ 2012-01-05  0:14                 ` Mark Langsdorf
  2012-01-05  0:22                   ` Peter Maydell
  0 siblings, 1 reply; 26+ messages in thread
From: Mark Langsdorf @ 2012-01-05  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, afaerber, Mark Langsdorf

Add dummy register support for the cp15, CRn=c15 registers and
for c1 SCR.

config_base_register and power_control_register currently
default to 0, but may have improved support after the QOM
CPU patches are finished.

Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
Changes from v7
	Formatted improved
	c1_scr added
	CPU_SAVE_VERSION increased
Changes from v6
	Added the diagnostic registers
	Added save/load support
Changes from v5
        Added handling for all c15 registers
Changes from v3, v4
        None
Changes from v2
        Added test against op2 
Changes from v1
        renamed the register
        added comments about how it will change when QOM CPUs are added

 target-arm/cpu.h     |    7 +++++-
 target-arm/helper.c  |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++
 target-arm/machine.c |    8 +++++++
 3 files changed, 71 insertions(+), 1 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c4d742f..cfc2063 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -116,6 +116,7 @@ typedef struct CPUARMState {
         uint32_t c1_sys; /* System control register.  */
         uint32_t c1_coproc; /* Coprocessor access register.  */
         uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
+        uint32_t c1_scr; /* secure config register.  */
         uint32_t c2_base0; /* MMU translation table base 0.  */
         uint32_t c2_base1; /* MMU translation table base 1.  */
         uint32_t c2_control; /* MMU translation table base control.  */
@@ -149,6 +150,10 @@ typedef struct CPUARMState {
         uint32_t c15_i_max; /* Maximum D-cache dirty line index.  */
         uint32_t c15_i_min; /* Minimum D-cache dirty line index.  */
         uint32_t c15_threadid; /* TI debugger thread-ID.  */
+        uint32_t c15_config_base_address; /* SCU base address.  */
+        uint32_t c15_diagnostic; /* diagnostic register */
+        uint32_t c15_power_diagnostic;
+        uint32_t c15_power_control; /* power control */
     } cp15;
 
     struct {
@@ -448,7 +453,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
 #define cpu_signal_handler cpu_arm_signal_handler
 #define cpu_list arm_cpu_list
 
-#define CPU_SAVE_VERSION 4
+#define CPU_SAVE_VERSION 5
 
 /* MMU modes definitions */
 #define MMU_MODE0_SUFFIX _kernel
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 65f4fbf..acefd37 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1412,6 +1412,11 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
         }
         goto bad_reg;
     case 1: /* System configuration.  */
+        if (arm_feature(env, ARM_FEATURE_V7)
+                && op1 == 0 && crm == 1 && op2 == 0) {
+            env->cp15.c1_scr = val;
+            break;
+        }
         if (arm_feature(env, ARM_FEATURE_OMAPCP))
             op2 = 0;
         switch (op2) {
@@ -1768,6 +1773,20 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
                 goto bad_reg;
             }
         }
+        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
+            switch (crm) {
+            case 0:
+                if ((op1 == 0) && (op2 == 0)) {
+                    env->cp15.c15_power_control = val;
+                } else if ((op1 == 0) && (op2 == 1)) {
+                    env->cp15.c15_diagnostic = val;
+                } else if ((op1 == 0) && (op2 == 2)) {
+                    env->cp15.c15_power_diagnostic = val;
+                }
+            default:
+                break;
+            }
+        }
         break;
     }
     return;
@@ -1866,6 +1885,10 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
             goto bad_reg;
         }
     case 1: /* System configuration.  */
+        if (arm_feature(env, ARM_FEATURE_V7)
+            && op1 == 0 && crm == 1 && op2 == 0) {
+            return env->cp15.c1_scr;
+        }
         if (arm_feature(env, ARM_FEATURE_OMAPCP))
             op2 = 0;
         switch (op2) {
@@ -2111,6 +2134,40 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
              * 0x200 << ($rn & 0xfff), when MMU is off.  */
             goto bad_reg;
         }
+        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
+            switch (crm) {
+            case 0:
+                if ((op1 == 4) && (op2 == 0)) {
+                    /* The config_base_address should hold the value of
+                     * the peripheral base. ARM should get this from a CPU
+                     * object property, but that support isn't available in
+                     * December 2011. Default to 0 for now and board models
+                     * that care can set it by a private hook */
+                    return env->cp15.c15_config_base_address;
+                } else if ((op1 == 0) && (op2 == 0)) {
+                    /* power_control should be set to maximum latency. Again,
+                       default to 0 and set by private hook */
+                    return env->cp15.c15_power_control;
+                } else if ((op1 == 0) && (op2 == 1)) {
+                    return env->cp15.c15_diagnostic;
+                } else if ((op1 == 0) && (op2 == 2)) {
+                    return env->cp15.c15_power_diagnostic;
+                }
+                break;
+            case 1: /* NEON Busy */
+                return 0;
+            case 5: /* tlb lockdown */
+            case 6:
+            case 7:
+                if ((op1 == 5) && (op2 == 2)) {
+                    return 0;
+                }
+                break;
+            default:
+                break;
+            }
+            goto bad_reg;
+        }
         return 0;
     }
 bad_reg:
diff --git a/target-arm/machine.c b/target-arm/machine.c
index aaee9b9..f66b8df 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -26,6 +26,7 @@ void cpu_save(QEMUFile *f, void *opaque)
     qemu_put_be32(f, env->cp15.c1_sys);
     qemu_put_be32(f, env->cp15.c1_coproc);
     qemu_put_be32(f, env->cp15.c1_xscaleauxcr);
+    qemu_put_be32(f, env->cp15.c1_scr);
     qemu_put_be32(f, env->cp15.c2_base0);
     qemu_put_be32(f, env->cp15.c2_base1);
     qemu_put_be32(f, env->cp15.c2_control);
@@ -56,6 +57,9 @@ void cpu_save(QEMUFile *f, void *opaque)
     qemu_put_be32(f, env->cp15.c13_tls2);
     qemu_put_be32(f, env->cp15.c13_tls3);
     qemu_put_be32(f, env->cp15.c15_cpar);
+    qemu_put_be32(f, env->cp15.c15_power_control);
+    qemu_put_be32(f, env->cp15.c15_diagnostic);
+    qemu_put_be32(f, env->cp15.c15_power_diagnostic);
 
     qemu_put_be32(f, env->features);
 
@@ -140,6 +144,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     env->cp15.c1_sys = qemu_get_be32(f);
     env->cp15.c1_coproc = qemu_get_be32(f);
     env->cp15.c1_xscaleauxcr = qemu_get_be32(f);
+    env->cp15.c1_scr = qemu_get_be32(f);
     env->cp15.c2_base0 = qemu_get_be32(f);
     env->cp15.c2_base1 = qemu_get_be32(f);
     env->cp15.c2_control = qemu_get_be32(f);
@@ -170,6 +175,9 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     env->cp15.c13_tls2 = qemu_get_be32(f);
     env->cp15.c13_tls3 = qemu_get_be32(f);
     env->cp15.c15_cpar = qemu_get_be32(f);
+    env->cp15.c15_power_control = qemu_get_be32(f);
+    env->cp15.c15_diagnostic = qemu_get_be32(f);
+    env->cp15.c15_power_diagnostic = qemu_get_be32(f);
 
     env->features = qemu_get_be32(f);
 
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] [PATCH v8] arm: add dummy v7 cp15 registers
  2012-01-05  0:14                 ` [Qemu-devel] [PATCH v8] " Mark Langsdorf
@ 2012-01-05  0:22                   ` Peter Maydell
  2012-01-05  0:54                     ` Mark Langsdorf
  0 siblings, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2012-01-05  0:22 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: qemu-devel, afaerber

On 5 January 2012 00:14, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> Add dummy register support for the cp15, CRn=c15 registers and
> for c1 SCR.

Can you drop the SCR code, please? This needs to be done properly
as part of trustzone support, which is a different and rather larger
kettle of fish.

-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] [PATCH v8] arm: add dummy v7 cp15 registers
  2012-01-05  0:22                   ` Peter Maydell
@ 2012-01-05  0:54                     ` Mark Langsdorf
  2012-01-05  8:36                       ` Peter Maydell
  0 siblings, 1 reply; 26+ messages in thread
From: Mark Langsdorf @ 2012-01-05  0:54 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel@nongnu.org, afaerber@suse.de

On 01/04/2012 06:22 PM, Peter Maydell wrote:
> On 5 January 2012 00:14, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
>> Add dummy register support for the cp15, CRn=c15 registers and
>> for c1 SCR.
> 
> Can you drop the SCR code, please? This needs to be done properly
> as part of trustzone support, which is a different and rather larger
> kettle of fish.

I found out that the Highbank SoC model depends on the scr code
through four days of tedious debugging. Would it possible to keep
it in as a stub?

I'm still waiting on Kevin Wolf's review of the AHCI changes and
review of the last two patches from this series. I suppose I can
resubmit without scr and delay the SoC model for another while.

--Mark Langsdorf
Calxeda, Inc.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] [PATCH v8] arm: add dummy v7 cp15 registers
  2012-01-05  0:54                     ` Mark Langsdorf
@ 2012-01-05  8:36                       ` Peter Maydell
  2012-01-05 13:16                         ` [Qemu-devel] [PATCH v9] " Mark Langsdorf
  0 siblings, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2012-01-05  8:36 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: qemu-devel@nongnu.org, afaerber@suse.de

On 5 January 2012 00:54, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> On 01/04/2012 06:22 PM, Peter Maydell wrote:
>> Can you drop the SCR code, please? This needs to be done properly
>> as part of trustzone support, which is a different and rather larger
>> kettle of fish.
>
> I found out that the Highbank SoC model depends on the scr code
> through four days of tedious debugging. Would it possible to keep
> it in as a stub?

Regardless, it shouldn't be in this patch, because it's not related
to the A9-specific c15 registers.

I'll have a look at the docs and see if there's a sensible minimal
implementation of the SCR that we could implement.

> I'm still waiting on Kevin Wolf's review of the AHCI changes

You should post those as a separate 2-patch AHCI set, I think.

> and
> review of the last two patches from this series.

These are still on my todo list, I haven't forgotten them.
(However I still have a huge patchset from Samsung to review
which I should probably do first.)

-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [Qemu-devel] [PATCH v9] arm: add dummy v7 cp15 registers
  2012-01-05  8:36                       ` Peter Maydell
@ 2012-01-05 13:16                         ` Mark Langsdorf
  2012-01-05 15:33                           ` Peter Maydell
  0 siblings, 1 reply; 26+ messages in thread
From: Mark Langsdorf @ 2012-01-05 13:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, afaerber, Mark Langsdorf

Add dummy register support for the cp15, CRn=c15 registers.

config_base_register and power_control_register currently
default to 0, but may have improved support after the QOM
CPU patches are finished.

Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
Changes from v8
	Removed c1_scr
Changes from v7
        Formatted improved
        c1_scr added
        CPU_SAVE_VERSION increased
Changes from v6
        Added the diagnostic registers
        Added save/load support
Changes from v5
        Added handling for all c15 registers
Changes from v3, v4
        None
Changes from v2
        Added test against op2 
Changes from v1
        renamed the register
        added comments about how it will change when QOM CPUs are added

 target-arm/cpu.h     |    6 +++++-
 target-arm/helper.c  |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 target-arm/machine.c |    6 ++++++
 3 files changed, 59 insertions(+), 1 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c4d742f..26b4981 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -149,6 +149,10 @@ typedef struct CPUARMState {
         uint32_t c15_i_max; /* Maximum D-cache dirty line index.  */
         uint32_t c15_i_min; /* Minimum D-cache dirty line index.  */
         uint32_t c15_threadid; /* TI debugger thread-ID.  */
+        uint32_t c15_config_base_address; /* SCU base address.  */
+        uint32_t c15_diagnostic; /* diagnostic register */
+        uint32_t c15_power_diagnostic;
+        uint32_t c15_power_control; /* power control */
     } cp15;
 
     struct {
@@ -448,7 +452,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
 #define cpu_signal_handler cpu_arm_signal_handler
 #define cpu_list arm_cpu_list
 
-#define CPU_SAVE_VERSION 4
+#define CPU_SAVE_VERSION 5
 
 /* MMU modes definitions */
 #define MMU_MODE0_SUFFIX _kernel
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 65f4fbf..4cfda17 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1768,6 +1768,20 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
                 goto bad_reg;
             }
         }
+        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
+            switch (crm) {
+            case 0:
+                if ((op1 == 0) && (op2 == 0)) {
+                    env->cp15.c15_power_control = val;
+                } else if ((op1 == 0) && (op2 == 1)) {
+                    env->cp15.c15_diagnostic = val;
+                } else if ((op1 == 0) && (op2 == 2)) {
+                    env->cp15.c15_power_diagnostic = val;
+                }
+            default:
+                break;
+            }
+        }
         break;
     }
     return;
@@ -2111,6 +2125,40 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
              * 0x200 << ($rn & 0xfff), when MMU is off.  */
             goto bad_reg;
         }
+        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
+            switch (crm) {
+            case 0:
+                if ((op1 == 4) && (op2 == 0)) {
+                    /* The config_base_address should hold the value of
+                     * the peripheral base. ARM should get this from a CPU
+                     * object property, but that support isn't available in
+                     * December 2011. Default to 0 for now and board models
+                     * that care can set it by a private hook */
+                    return env->cp15.c15_config_base_address;
+                } else if ((op1 == 0) && (op2 == 0)) {
+                    /* power_control should be set to maximum latency. Again,
+                       default to 0 and set by private hook */
+                    return env->cp15.c15_power_control;
+                } else if ((op1 == 0) && (op2 == 1)) {
+                    return env->cp15.c15_diagnostic;
+                } else if ((op1 == 0) && (op2 == 2)) {
+                    return env->cp15.c15_power_diagnostic;
+                }
+                break;
+            case 1: /* NEON Busy */
+                return 0;
+            case 5: /* tlb lockdown */
+            case 6:
+            case 7:
+                if ((op1 == 5) && (op2 == 2)) {
+                    return 0;
+                }
+                break;
+            default:
+                break;
+            }
+            goto bad_reg;
+        }
         return 0;
     }
 bad_reg:
diff --git a/target-arm/machine.c b/target-arm/machine.c
index aaee9b9..8984775 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -56,6 +56,9 @@ void cpu_save(QEMUFile *f, void *opaque)
     qemu_put_be32(f, env->cp15.c13_tls2);
     qemu_put_be32(f, env->cp15.c13_tls3);
     qemu_put_be32(f, env->cp15.c15_cpar);
+    qemu_put_be32(f, env->cp15.c15_power_control);
+    qemu_put_be32(f, env->cp15.c15_diagnostic);
+    qemu_put_be32(f, env->cp15.c15_power_diagnostic);
 
     qemu_put_be32(f, env->features);
 
@@ -170,6 +173,9 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     env->cp15.c13_tls2 = qemu_get_be32(f);
     env->cp15.c13_tls3 = qemu_get_be32(f);
     env->cp15.c15_cpar = qemu_get_be32(f);
+    env->cp15.c15_power_control = qemu_get_be32(f);
+    env->cp15.c15_diagnostic = qemu_get_be32(f);
+    env->cp15.c15_power_diagnostic = qemu_get_be32(f);
 
     env->features = qemu_get_be32(f);
 
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] [PATCH v9] arm: add dummy v7 cp15 registers
  2012-01-05 13:16                         ` [Qemu-devel] [PATCH v9] " Mark Langsdorf
@ 2012-01-05 15:33                           ` Peter Maydell
  2012-01-05 15:34                             ` Mark Langsdorf
  0 siblings, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2012-01-05 15:33 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: qemu-devel, afaerber

On 5 January 2012 13:16, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
> Add dummy register support for the cp15, CRn=c15 registers.
>
> config_base_register and power_control_register currently
> default to 0, but may have improved support after the QOM
> CPU patches are finished.
>
> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
and put into target-arm.next.
(I've taken the liberty of tweaking the patch summary -- these
are A9-specific, not v7).

-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] [PATCH v9] arm: add dummy v7 cp15 registers
  2012-01-05 15:33                           ` Peter Maydell
@ 2012-01-05 15:34                             ` Mark Langsdorf
  0 siblings, 0 replies; 26+ messages in thread
From: Mark Langsdorf @ 2012-01-05 15:34 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel@nongnu.org, afaerber@suse.de

On 01/05/2012 09:33 AM, Peter Maydell wrote:
> On 5 January 2012 13:16, Mark Langsdorf <mark.langsdorf@calxeda.com> wrote:
>> Add dummy register support for the cp15, CRn=c15 registers.
>>
>> config_base_register and power_control_register currently
>> default to 0, but may have improved support after the QOM
>> CPU patches are finished.
>>
>> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
> 
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> and put into target-arm.next.
> (I've taken the liberty of tweaking the patch summary -- these
> are A9-specific, not v7).

Ack.

--Mark Langsdorf
Calxeda, Inc.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] [PATCH v5 5/5] add L2x0/PL310 cache controller device
  2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 5/5] add L2x0/PL310 cache controller device Mark Langsdorf
  2012-01-04 13:29   ` Peter Maydell
@ 2012-06-07 13:45   ` Andreas Färber
  2012-06-07 14:21     ` Mark Langsdorf
  1 sibling, 1 reply; 26+ messages in thread
From: Andreas Färber @ 2012-06-07 13:45 UTC (permalink / raw)
  To: Mark Langsdorf; +Cc: peter.maydell, qemu-devel, rob.herring, Paolo Bonzini

Am 29.12.2011 17:19, schrieb Mark Langsdorf:
> From: Rob Herring <rob.herring@calxeda.com>
> 
> This is just a dummy device for ARM L2 cache controllers, based on the
> pl310. The cache type parameter can be defined by a property value
> and has a meaningful default.
> 
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>

> diff --git a/hw/arm_l2x0.c b/hw/arm_l2x0.c
> new file mode 100644
> index 0000000..ba106f1
> --- /dev/null
> +++ b/hw/arm_l2x0.c
[...]
> +static SysBusDeviceInfo l2x0_info = {
> +    .init = l2x0_priv_init,
> +    .qdev.name = "l2x0",
> +    .qdev.size = sizeof(l2x0_state),
> +    .qdev.vmsd = &vmstate_l2x0,
> +    .qdev.no_user = 1,
> +    .qdev.props = (Property[]) {
> +        DEFINE_PROP_UINT32("type", l2x0_state, cache_type, 0x1c100100),

Mark, this "type" property conflicts with a QOM refactoring by Paolo.
Mind if we rename it to "cache-type"? It always has its default value in
upstream.

Thanks,
Andreas

> +        DEFINE_PROP_END_OF_LIST(),
> +    },
> +    .qdev.reset = l2x0_priv_reset,
> +};
> +
> +static void l2x0_register_device(void)
> +{
> +    sysbus_register_withprop(&l2x0_info);
> +}
> +
> +device_init(l2x0_register_device)
> +


-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] [PATCH v5 5/5] add L2x0/PL310 cache controller device
  2012-06-07 13:45   ` Andreas Färber
@ 2012-06-07 14:21     ` Mark Langsdorf
  0 siblings, 0 replies; 26+ messages in thread
From: Mark Langsdorf @ 2012-06-07 14:21 UTC (permalink / raw)
  To: Andreas Färber
  Cc: peter.maydell@linaro.org, qemu-devel@nongnu.org, Rob Herring,
	Paolo Bonzini

Yes, that's fine by me.

--Mark Langsdorf
Calxeda, Inc.

________________________________________
From: Andreas Färber [afaerber@suse.de]
Sent: Thursday, June 07, 2012 8:45 AM
To: Mark Langsdorf
Cc: qemu-devel@nongnu.org; peter.maydell@linaro.org; Rob Herring; Paolo Bonzini
Subject: Re: [Qemu-devel] [PATCH v5 5/5] add L2x0/PL310 cache controller device

Am 29.12.2011 17:19, schrieb Mark Langsdorf:
> From: Rob Herring <rob.herring@calxeda.com>
>
> This is just a dummy device for ARM L2 cache controllers, based on the
> pl310. The cache type parameter can be defined by a property value
> and has a meaningful default.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>

> diff --git a/hw/arm_l2x0.c b/hw/arm_l2x0.c
> new file mode 100644
> index 0000000..ba106f1
> --- /dev/null
> +++ b/hw/arm_l2x0.c
[...]
> +static SysBusDeviceInfo l2x0_info = {
> +    .init = l2x0_priv_init,
> +    .qdev.name = "l2x0",
> +    .qdev.size = sizeof(l2x0_state),
> +    .qdev.vmsd = &vmstate_l2x0,
> +    .qdev.no_user = 1,
> +    .qdev.props = (Property[]) {
> +        DEFINE_PROP_UINT32("type", l2x0_state, cache_type, 0x1c100100),

Mark, this "type" property conflicts with a QOM refactoring by Paolo.
Mind if we rename it to "cache-type"? It always has its default value in
upstream.

Thanks,
Andreas

> +        DEFINE_PROP_END_OF_LIST(),
> +    },
> +    .qdev.reset = l2x0_priv_reset,
> +};
> +
> +static void l2x0_register_device(void)
> +{
> +    sysbus_register_withprop(&l2x0_info);
> +}
> +
> +device_init(l2x0_register_device)
> +


--
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2012-06-07 14:22 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-29 16:19 [Qemu-devel] [PATCH v5 0/7] various ARM fixes for Calxeda Highbank Mark Langsdorf
2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 1/7] arm: add missing scu registers Mark Langsdorf
2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 2/7] arm: Set frequencies for arm_timer Mark Langsdorf
2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 3/7] arm: add dummy v7 cp15 config_base_register Mark Langsdorf
2012-01-04 14:32   ` Peter Maydell
2012-01-04 16:32     ` Mark Langsdorf
2012-01-04 16:47       ` Peter Maydell
2012-01-04 16:53         ` [Qemu-devel] [PATCH v6 1/1] arm: add dummy v7 cp15 registers Mark Langsdorf
2012-01-04 17:50           ` Peter Maydell
2012-01-04 18:23             ` Mark Langsdorf
2012-01-04 19:07             ` [Qemu-devel] [PATCH v7] " Mark Langsdorf
2012-01-04 23:50               ` Peter Maydell
2012-01-05  0:14                 ` [Qemu-devel] [PATCH v8] " Mark Langsdorf
2012-01-05  0:22                   ` Peter Maydell
2012-01-05  0:54                     ` Mark Langsdorf
2012-01-05  8:36                       ` Peter Maydell
2012-01-05 13:16                         ` [Qemu-devel] [PATCH v9] " Mark Langsdorf
2012-01-05 15:33                           ` Peter Maydell
2012-01-05 15:34                             ` Mark Langsdorf
2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 4/7] arm: add dummy gic security registers Mark Langsdorf
2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 5/5] add L2x0/PL310 cache controller device Mark Langsdorf
2012-01-04 13:29   ` Peter Maydell
2012-06-07 13:45   ` Andreas Färber
2012-06-07 14:21     ` Mark Langsdorf
2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 6/7] Add xgmac ethernet model Mark Langsdorf
2011-12-29 16:19 ` [Qemu-devel] [PATCH v5 7/7] arm: make the number of GIC interrupts configurable Mark Langsdorf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).