All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/16] arm-devs queue
@ 2012-06-19 13:30 Peter Maydell
  2012-06-19 13:30 ` [Qemu-devel] [PATCH 01/16] ARM: Exynos4210 IRQ: Introduce new IRQ gate functionality Peter Maydell
                   ` (16 more replies)
  0 siblings, 17 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:30 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Hi; this is an arm-devs pullreq which mostly has patches which I've
had queued since before freeze and my holiday. (I had to make a
trivial fix to one of the GIC patches to account for the list of
object files moving from Makefile.target to hw/arm/Makefile.objs
but otherwise an unproblematic rebase to current master.)
I know there are other arm devs patches on my to-review list but
this seems a long enough set of patches to be worth sending a
pullreq for now.

Please pull.

-- PMM

The following changes since commit 8aca521512a14c439624191bd0a891c52f91b401:

  Merge remote-tracking branch 'afaerber-or/qom-next-2' into staging (2012-06-18 10:35:16 -0500)

are available in the git repository at:

  git://git.linaro.org/people/pmaydell/qemu-arm.git arm-devs.for-upstream

Andreas Färber (1):
      arm_boot: Fix typos in comment

Evgeny Voevodin (1):
      ARM: Exynos4210 IRQ: Introduce new IRQ gate functionality.

Jim Meyering (1):
      cadence_gem: avoid stack-writing buffer-overrun

Peter A. G. Crosthwaite (2):
      cadence_ttc: changed master clock frequency
      arm_boot: Conditionalised DTB command line update

Peter Maydell (11):
      hw/arm_gic: Remove NVIC ifdefs from gic_state struct
      hw/arm_gic: Remove the special casing of NCPU for the NVIC
      hw/arm_gic: Move NVIC specific reset to armv7m_nvic_reset
      hw/armv7m_nvic: Use MemoryRegions for NVIC specific registers
      hw/arm_gic: Add qdev property for GIC revision
      hw/arm_gic: Make CPU target registers RAZ/WI on uniprocessor
      hw/arm_gic.c: Make NVIC interrupt numbering a runtime setting
      hw/arm_gic: Move CPU interface memory region setup into arm_gic_init
      hw/armv7m_nvic: Make the NVIC a freestanding class
      hw/omap.h: Drop broken MEM_VERBOSE tracing
      hw/a9mpcore: Fix compilation failure if physaddrs are 64 bit

 hw/a15mpcore.c        |    1 +
 hw/a9mpcore.c         |    2 +-
 hw/arm-misc.h         |    4 +-
 hw/arm/Makefile.objs  |    2 +-
 hw/arm11mpcore.c      |    2 +
 hw/arm_boot.c         |   10 +-
 hw/arm_gic.c          |  366 ++++++++-----------------------------------------
 hw/arm_gic_common.c   |  184 +++++++++++++++++++++++++
 hw/arm_gic_internal.h |  136 ++++++++++++++++++
 hw/armv7m_nvic.c      |  138 ++++++++++++++++---
 hw/cadence_gem.c      |    2 +-
 hw/cadence_ttc.c      |    2 +-
 hw/exynos4210.c       |   32 +++--
 hw/exynos4210.h       |    2 +-
 hw/exynos4210_gic.c   |   78 +++++-----
 hw/omap.h             |   95 -------------
 16 files changed, 569 insertions(+), 487 deletions(-)
 create mode 100644 hw/arm_gic_common.c
 create mode 100644 hw/arm_gic_internal.h

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

* [Qemu-devel] [PATCH 01/16] ARM: Exynos4210 IRQ: Introduce new IRQ gate functionality.
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
@ 2012-06-19 13:30 ` Peter Maydell
  2012-06-19 13:30 ` [Qemu-devel] [PATCH 02/16] arm_boot: Fix typos in comment Peter Maydell
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:30 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

From: Evgeny Voevodin <e.voevodin@samsung.com>

New IRQ gate consists of n_in input qdev gpio lines and one
output sysbus IRQ line. The output IRQ level is formed as OR
between all gpio inputs.

Signed-off-by: Evgeny Voevodin <e.voevodin@samsung.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/exynos4210.c     |   32 +++++++++++----------
 hw/exynos4210.h     |    2 +-
 hw/exynos4210_gic.c |   78 +++++++++++++++++++++++++-------------------------
 3 files changed, 57 insertions(+), 55 deletions(-)

diff --git a/hw/exynos4210.c b/hw/exynos4210.c
index dd14d01..9c20b3f 100644
--- a/hw/exynos4210.c
+++ b/hw/exynos4210.c
@@ -97,11 +97,11 @@ void exynos4210_write_secondary(ARMCPU *cpu,
 Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
         unsigned long ram_size)
 {
-    qemu_irq cpu_irq[4];
-    int n;
+    qemu_irq cpu_irq[EXYNOS4210_NCPUS];
+    int i, n;
     Exynos4210State *s = g_new(Exynos4210State, 1);
     qemu_irq *irqp;
-    qemu_irq gate_irq[EXYNOS4210_IRQ_GATE_NINPUTS];
+    qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
     unsigned long mem_size;
     DeviceState *dev;
     SysBusDevice *busdev;
@@ -128,16 +128,18 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
     s->irq_table = exynos4210_init_irq(&s->irqs);
 
     /* IRQ Gate */
-    dev = qdev_create(NULL, "exynos4210.irq_gate");
-    qdev_init_nofail(dev);
-    /* Get IRQ Gate input in gate_irq */
-    for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
-        gate_irq[n] = qdev_get_gpio_in(dev, n);
-    }
-    busdev = sysbus_from_qdev(dev);
-    /* Connect IRQ Gate output to cpu_irq */
-    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
-        sysbus_connect_irq(busdev, n, cpu_irq[n]);
+    for (i = 0; i < EXYNOS4210_NCPUS; i++) {
+        dev = qdev_create(NULL, "exynos4210.irq_gate");
+        qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
+        qdev_init_nofail(dev);
+        /* Get IRQ Gate input in gate_irq */
+        for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
+            gate_irq[i][n] = qdev_get_gpio_in(dev, n);
+        }
+        busdev = sysbus_from_qdev(dev);
+
+        /* Connect IRQ Gate output to cpu_irq */
+        sysbus_connect_irq(busdev, 0, cpu_irq[i]);
     }
 
     /* Private memory region and Internal GIC */
@@ -147,7 +149,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
     busdev = sysbus_from_qdev(dev);
     sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
     for (n = 0; n < EXYNOS4210_NCPUS; n++) {
-        sysbus_connect_irq(busdev, n, gate_irq[n * 2]);
+        sysbus_connect_irq(busdev, n, gate_irq[n][0]);
     }
     for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
         s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
@@ -166,7 +168,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
     /* Map Distributer interface */
     sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
     for (n = 0; n < EXYNOS4210_NCPUS; n++) {
-        sysbus_connect_irq(busdev, n, gate_irq[n * 2 + 1]);
+        sysbus_connect_irq(busdev, n, gate_irq[n][1]);
     }
     for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
         s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
diff --git a/hw/exynos4210.h b/hw/exynos4210.h
index b1b4609..9b1ae4c 100644
--- a/hw/exynos4210.h
+++ b/hw/exynos4210.h
@@ -56,7 +56,7 @@
 /*
  * exynos4210 IRQ subsystem stub definitions.
  */
-#define EXYNOS4210_IRQ_GATE_NINPUTS 8
+#define EXYNOS4210_IRQ_GATE_NINPUTS 2 /* Internal and External GIC */
 
 #define EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ  64
 #define EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ  16
diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
index e1b215e..7d03dd9 100644
--- a/hw/exynos4210_gic.c
+++ b/hw/exynos4210_gic.c
@@ -362,61 +362,64 @@ static void exynos4210_gic_register_types(void)
 
 type_init(exynos4210_gic_register_types)
 
-/*
- * IRQGate struct.
- * IRQ Gate represents OR gate between GICs to pass IRQ to PIC.
+/* IRQ OR Gate struct.
+ *
+ * This device models an OR gate. There are n_in input qdev gpio lines and one
+ * output sysbus IRQ line. The output IRQ level is formed as OR between all
+ * gpio inputs.
  */
 typedef struct {
     SysBusDevice busdev;
 
-    qemu_irq pic_irq[EXYNOS4210_NCPUS]; /* output IRQs to PICs */
-    uint32_t gpio_level[EXYNOS4210_IRQ_GATE_NINPUTS]; /* Input levels */
+    uint32_t n_in;      /* inputs amount */
+    uint32_t *level;    /* input levels */
+    qemu_irq out;       /* output IRQ */
 } Exynos4210IRQGateState;
 
+static Property exynos4210_irq_gate_properties[] = {
+    DEFINE_PROP_UINT32("n_in", Exynos4210IRQGateState, n_in, 1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static const VMStateDescription vmstate_exynos4210_irq_gate = {
     .name = "exynos4210.irq_gate",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .minimum_version_id_old = 2,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT32_ARRAY(gpio_level, Exynos4210IRQGateState,
-                EXYNOS4210_IRQ_GATE_NINPUTS),
+        VMSTATE_VBUFFER_UINT32(level, Exynos4210IRQGateState, 1, NULL, 0, n_in),
         VMSTATE_END_OF_LIST()
     }
 };
 
-/* Process a change in an external IRQ input.  */
+/* Process a change in IRQ input. */
 static void exynos4210_irq_gate_handler(void *opaque, int irq, int level)
 {
-    Exynos4210IRQGateState *s =
-            (Exynos4210IRQGateState *)opaque;
-    uint32_t odd, even;
-
-    if (irq & 1) {
-        odd = irq;
-        even = irq & ~1;
-    } else {
-        even = irq;
-        odd = irq | 1;
-    }
+    Exynos4210IRQGateState *s = (Exynos4210IRQGateState *)opaque;
+    uint32_t i;
 
-    assert(irq < EXYNOS4210_IRQ_GATE_NINPUTS);
-    s->gpio_level[irq] = level;
+    assert(irq < s->n_in);
 
-    if (s->gpio_level[odd] >= 1 || s->gpio_level[even] >= 1) {
-        qemu_irq_raise(s->pic_irq[even >> 1]);
-    } else {
-        qemu_irq_lower(s->pic_irq[even >> 1]);
+    s->level[irq] = level;
+
+    for (i = 0; i < s->n_in; i++) {
+        if (s->level[i] >= 1) {
+            qemu_irq_raise(s->out);
+            return;
+        }
     }
 
+    qemu_irq_lower(s->out);
+
     return;
 }
 
 static void exynos4210_irq_gate_reset(DeviceState *d)
 {
-    Exynos4210IRQGateState *s = (Exynos4210IRQGateState *)d;
+    Exynos4210IRQGateState *s =
+            DO_UPCAST(Exynos4210IRQGateState, busdev.qdev, d);
 
-    memset(&s->gpio_level, 0, sizeof(s->gpio_level));
+    memset(s->level, 0, s->n_in * sizeof(*s->level));
 }
 
 /*
@@ -424,19 +427,15 @@ static void exynos4210_irq_gate_reset(DeviceState *d)
  */
 static int exynos4210_irq_gate_init(SysBusDevice *dev)
 {
-    unsigned int i;
-    Exynos4210IRQGateState *s =
-            FROM_SYSBUS(Exynos4210IRQGateState, dev);
+    Exynos4210IRQGateState *s = FROM_SYSBUS(Exynos4210IRQGateState, dev);
 
     /* Allocate general purpose input signals and connect a handler to each of
      * them */
-    qdev_init_gpio_in(&s->busdev.qdev, exynos4210_irq_gate_handler,
-            EXYNOS4210_IRQ_GATE_NINPUTS);
+    qdev_init_gpio_in(&s->busdev.qdev, exynos4210_irq_gate_handler, s->n_in);
 
-    /* Connect SysBusDev irqs to device specific irqs */
-    for (i = 0; i < EXYNOS4210_NCPUS; i++) {
-        sysbus_init_irq(dev, &s->pic_irq[i]);
-    }
+    s->level = g_malloc0(s->n_in * sizeof(*s->level));
+
+    sysbus_init_irq(dev, &s->out);
 
     return 0;
 }
@@ -449,6 +448,7 @@ static void exynos4210_irq_gate_class_init(ObjectClass *klass, void *data)
     k->init = exynos4210_irq_gate_init;
     dc->reset = exynos4210_irq_gate_reset;
     dc->vmsd = &vmstate_exynos4210_irq_gate;
+    dc->props = exynos4210_irq_gate_properties;
 }
 
 static TypeInfo exynos4210_irq_gate_info = {
-- 
1.7.1

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

* [Qemu-devel] [PATCH 02/16] arm_boot: Fix typos in comment
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
  2012-06-19 13:30 ` [Qemu-devel] [PATCH 01/16] ARM: Exynos4210 IRQ: Introduce new IRQ gate functionality Peter Maydell
@ 2012-06-19 13:30 ` Peter Maydell
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 03/16] hw/arm_gic: Remove NVIC ifdefs from gic_state struct Peter Maydell
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:30 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

From: Andreas Färber <afaerber@suse.de>

mimicing -> mimicking
thei -> the

Signed-off-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm-misc.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm-misc.h b/hw/arm-misc.h
index 1d51570..1f96229 100644
--- a/hw/arm-misc.h
+++ b/hw/arm-misc.h
@@ -45,9 +45,9 @@ struct arm_boot_info {
     /* multicore boards that use the default secondary core boot functions
      * can ignore these two function calls. If the default functions won't
      * work, then write_secondary_boot() should write a suitable blob of
-     * code mimicing the secondary CPU startup process used by the board's
+     * code mimicking the secondary CPU startup process used by the board's
      * boot loader/boot ROM code, and secondary_cpu_reset_hook() should
-     * perform any necessary CPU reset handling and set the PC for thei
+     * perform any necessary CPU reset handling and set the PC for the
      * secondary CPUs to point at this boot blob.
      */
     void (*write_secondary_boot)(ARMCPU *cpu,
-- 
1.7.1

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

* [Qemu-devel] [PATCH 03/16] hw/arm_gic: Remove NVIC ifdefs from gic_state struct
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
  2012-06-19 13:30 ` [Qemu-devel] [PATCH 01/16] ARM: Exynos4210 IRQ: Introduce new IRQ gate functionality Peter Maydell
  2012-06-19 13:30 ` [Qemu-devel] [PATCH 02/16] arm_boot: Fix typos in comment Peter Maydell
@ 2012-06-19 13:31 ` Peter Maydell
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 04/16] hw/arm_gic: Remove the special casing of NCPU for the NVIC Peter Maydell
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:31 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Remove some NVIC ifdefs from the gic_state struct and its
state save/load functions. This means there are some fields
in it which are present for the NVIC but not used, but means
it always has the same layout and can be pulled out into a
common subclass.

Note that the addition of irq_target[] to the save/load
struct for the NVIC requires a vmstate version bump.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andreas Färber <afaerber@suse.de>
---
 hw/arm_gic.c |   15 +++------------
 1 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 72298b4..17b2eba 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -108,9 +108,7 @@ typedef struct gic_state
     int cpu_enabled[NCPU];
 
     gic_irq_state irq_state[GIC_MAXIRQ];
-#ifndef NVIC
     int irq_target[GIC_MAXIRQ];
-#endif
     int priority1[GIC_INTERNAL][NCPU];
     int priority2[GIC_MAXIRQ - GIC_INTERNAL];
     int last_active[GIC_MAXIRQ][NCPU];
@@ -120,18 +118,14 @@ typedef struct gic_state
     int running_priority[NCPU];
     int current_pending[NCPU];
 
-#if NCPU > 1
     uint32_t num_cpu;
-#endif
 
     MemoryRegion iomem; /* Distributor */
-#ifndef NVIC
     /* This is just so we can have an opaque pointer which identifies
      * both this GIC and which CPU interface we should be accessing.
      */
     struct gic_state *backref[NCPU];
     MemoryRegion cpuiomem[NCPU+1]; /* CPU interfaces */
-#endif
     uint32_t num_irq;
 } gic_state;
 
@@ -800,9 +794,7 @@ static void gic_save(QEMUFile *f, void *opaque)
         qemu_put_be32(f, s->priority2[i]);
     }
     for (i = 0; i < s->num_irq; i++) {
-#ifndef NVIC
         qemu_put_be32(f, s->irq_target[i]);
-#endif
         qemu_put_byte(f, s->irq_state[i].enabled);
         qemu_put_byte(f, s->irq_state[i].pending);
         qemu_put_byte(f, s->irq_state[i].active);
@@ -818,8 +810,9 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id)
     int i;
     int j;
 
-    if (version_id != 2)
+    if (version_id != 3) {
         return -EINVAL;
+    }
 
     s->enabled = qemu_get_be32(f);
     for (i = 0; i < NUM_CPU(s); i++) {
@@ -837,9 +830,7 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id)
         s->priority2[i] = qemu_get_be32(f);
     }
     for (i = 0; i < s->num_irq; i++) {
-#ifndef NVIC
         s->irq_target[i] = qemu_get_be32(f);
-#endif
         s->irq_state[i].enabled = qemu_get_byte(f);
         s->irq_state[i].pending = qemu_get_byte(f);
         s->irq_state[i].active = qemu_get_byte(f);
@@ -914,7 +905,7 @@ static void gic_init(gic_state *s, int num_irq)
     }
 #endif
 
-    register_savevm(NULL, "arm_gic", -1, 2, gic_save, gic_load, s);
+    register_savevm(NULL, "arm_gic", -1, 3, gic_save, gic_load, s);
 }
 
 #ifndef NVIC
-- 
1.7.1

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

* [Qemu-devel] [PATCH 04/16] hw/arm_gic: Remove the special casing of NCPU for the NVIC
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
                   ` (2 preceding siblings ...)
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 03/16] hw/arm_gic: Remove NVIC ifdefs from gic_state struct Peter Maydell
@ 2012-06-19 13:31 ` Peter Maydell
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 05/16] hw/arm_gic: Move NVIC specific reset to armv7m_nvic_reset Peter Maydell
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:31 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Drop the special casing of NCPU=1 for the NVIC. This slightly
increases the amount of memory used by its state structure,
but removes some ifdeffery and means we can safely move the
GIC state into a common subclass structure.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm_gic.c     |   23 +++--------------------
 hw/armv7m_nvic.c |    5 ++---
 2 files changed, 5 insertions(+), 23 deletions(-)

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 17b2eba..2d8ceb8 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -25,11 +25,7 @@
 /* First 32 are private to each CPU (SGIs and PPIs). */
 #define GIC_INTERNAL 32
 /* Maximum number of possible CPU interfaces, determined by GIC architecture */
-#ifdef NVIC
-#define NCPU 1
-#else
 #define NCPU 8
-#endif
 
 //#define DEBUG_GIC
 
@@ -67,11 +63,7 @@ typedef struct gic_irq_state
 } gic_irq_state;
 
 #define ALL_CPU_MASK ((unsigned)(((1 << NCPU) - 1)))
-#if NCPU > 1
 #define NUM_CPU(s) ((s)->num_cpu)
-#else
-#define NUM_CPU(s) 1
-#endif
 
 #define GIC_SET_ENABLED(irq, cm) s->irq_state[irq].enabled |= (cm)
 #define GIC_CLEAR_ENABLED(irq, cm) s->irq_state[irq].enabled &= ~(cm)
@@ -131,11 +123,9 @@ typedef struct gic_state
 
 static inline int gic_get_current_cpu(gic_state *s)
 {
-#if NCPU > 1
     if (s->num_cpu > 1) {
         return cpu_single_env->cpu_index;
     }
-#endif
     return 0;
 }
 
@@ -842,21 +832,14 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-#if NCPU > 1
-static void gic_init(gic_state *s, int num_cpu, int num_irq)
-#else
 static void gic_init(gic_state *s, int num_irq)
-#endif
 {
     int i;
 
-#if NCPU > 1
-    s->num_cpu = num_cpu;
     if (s->num_cpu > NCPU) {
         hw_error("requested %u CPUs exceeds GIC maximum %d\n",
-                 num_cpu, NCPU);
+                 s->num_cpu, NCPU);
     }
-#endif
     s->num_irq = num_irq + GIC_BASE_IRQ;
     if (s->num_irq > GIC_MAXIRQ) {
         hw_error("requested %u interrupt lines exceeds GIC maximum %d\n",
@@ -880,7 +863,7 @@ static void gic_init(gic_state *s, int num_irq)
      *  [N+32..N+63] PPIs for CPU 1
      *   ...
      */
-    i += (GIC_INTERNAL * num_cpu);
+    i += (GIC_INTERNAL * s->num_cpu);
 #endif
     qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, i);
     for (i = 0; i < NUM_CPU(s); i++) {
@@ -915,7 +898,7 @@ static int arm_gic_init(SysBusDevice *dev)
     /* Device instance init function for the GIC sysbus device */
     int i;
     gic_state *s = FROM_SYSBUS(gic_state, dev);
-    gic_init(s, s->num_cpu, s->num_irq);
+    gic_init(s, s->num_irq);
     /* Distributor */
     sysbus_init_mmio(dev, &s->iomem);
     /* cpu interfaces (one for "current cpu" plus one per cpu) */
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 986a6bb..99a87a2 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -389,9 +389,8 @@ static int armv7m_nvic_init(SysBusDevice *dev)
 {
     nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev);
 
-   /* note that for the M profile gic_init() takes the number of external
-    * interrupt lines only.
-    */
+    /* The NVIC always has only one CPU */
+    s->gic.num_cpu = 1;
     gic_init(&s->gic, s->num_irq);
     memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->gic.iomem);
     s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s);
-- 
1.7.1

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

* [Qemu-devel] [PATCH 05/16] hw/arm_gic: Move NVIC specific reset to armv7m_nvic_reset
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
                   ` (3 preceding siblings ...)
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 04/16] hw/arm_gic: Remove the special casing of NCPU for the NVIC Peter Maydell
@ 2012-06-19 13:31 ` Peter Maydell
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 06/16] hw/armv7m_nvic: Use MemoryRegions for NVIC specific registers Peter Maydell
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:31 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Move the NVIC specific bits of reset to the NVIC's own
reset function, rather than using ifdefs in the common
arm_gic reset.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm_gic.c     |   10 ----------
 hw/armv7m_nvic.c |    7 +++++++
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 2d8ceb8..3293ae4 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -743,23 +743,13 @@ static void gic_reset(DeviceState *dev)
         s->current_pending[i] = 1023;
         s->running_irq[i] = 1023;
         s->running_priority[i] = 0x100;
-#ifdef NVIC
-        /* The NVIC doesn't have per-cpu interfaces, so enable by default.  */
-        s->cpu_enabled[i] = 1;
-#else
         s->cpu_enabled[i] = 0;
-#endif
     }
     for (i = 0; i < 16; i++) {
         GIC_SET_ENABLED(i, ALL_CPU_MASK);
         GIC_SET_TRIGGER(i);
     }
-#ifdef NVIC
-    /* The NVIC is always enabled.  */
-    s->enabled = 1;
-#else
     s->enabled = 0;
-#endif
 }
 
 static void gic_save(QEMUFile *f, void *opaque)
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 99a87a2..653c011 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -382,6 +382,13 @@ static void armv7m_nvic_reset(DeviceState *dev)
 {
     nvic_state *s = FROM_SYSBUSGIC(nvic_state, sysbus_from_qdev(dev));
     gic_reset(&s->gic.busdev.qdev);
+    /* Common GIC reset resets to disabled; the NVIC doesn't have
+     * per-CPU interfaces so mark our non-existent CPU interface
+     * as enabled by default.
+     */
+    s->gic.cpu_enabled[0] = 1;
+    /* The NVIC as a whole is always enabled. */
+    s->gic.enabled = 1;
     systick_reset(s);
 }
 
-- 
1.7.1

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

* [Qemu-devel] [PATCH 06/16] hw/armv7m_nvic: Use MemoryRegions for NVIC specific registers
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
                   ` (4 preceding siblings ...)
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 05/16] hw/arm_gic: Move NVIC specific reset to armv7m_nvic_reset Peter Maydell
@ 2012-06-19 13:31 ` Peter Maydell
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 07/16] hw/arm_gic: Add qdev property for GIC revision Peter Maydell
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:31 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Implement the NVIC specific register areas using a set of
overlaid MemoryRegions in a container, rather than by having
the arm_gic read/write functions use special purpose callbacks.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm_gic.c     |   33 ++++-------------------
 hw/armv7m_nvic.c |   74 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 79 insertions(+), 28 deletions(-)

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 3293ae4..2ec10ce 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -37,17 +37,17 @@ do { printf("arm_gic: " fmt , ## __VA_ARGS__); } while (0)
 #endif
 
 #ifdef NVIC
-static const uint8_t gic_id[] =
-{ 0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1 };
 /* The NVIC has 16 internal vectors.  However these are not exposed
    through the normal GIC interface.  */
 #define GIC_BASE_IRQ    32
 #else
-static const uint8_t gic_id[] =
-{ 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
 #define GIC_BASE_IRQ    0
 #endif
 
+static const uint8_t gic_id[] = {
+    0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1
+};
+
 #define FROM_SYSBUSGIC(type, dev) \
     DO_UPCAST(type, gic, FROM_SYSBUS(gic_state, dev))
 
@@ -312,7 +312,6 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
     cpu = gic_get_current_cpu(s);
     cm = 1 << cpu;
     if (offset < 0x100) {
-#ifndef NVIC
         if (offset == 0)
             return s->enabled;
         if (offset == 4)
@@ -323,7 +322,6 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
             /* Interrupt Security , RAZ/WI */
             return 0;
         }
-#endif
         goto bad_reg;
     } else if (offset < 0x200) {
         /* Interrupt Set/Clear Enable.  */
@@ -385,6 +383,7 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
         } else {
             res = GIC_TARGET(irq);
         }
+#endif
     } else if (offset < 0xf00) {
         /* Interrupt Configuration.  */
         irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ;
@@ -397,7 +396,6 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
             if (GIC_TEST_TRIGGER(irq + i))
                 res |= (2 << (i * 2));
         }
-#endif
     } else if (offset < 0xfe0) {
         goto bad_reg;
     } else /* offset >= 0xfe0 */ {
@@ -424,13 +422,6 @@ static uint32_t gic_dist_readw(void *opaque, target_phys_addr_t offset)
 static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset)
 {
     uint32_t val;
-#ifdef NVIC
-    gic_state *s = (gic_state *)opaque;
-    uint32_t addr;
-    addr = offset;
-    if (addr < 0x100 || addr > 0xd00)
-        return nvic_readl(s, addr);
-#endif
     val = gic_dist_readw(opaque, offset);
     val |= gic_dist_readw(opaque, offset + 2) << 16;
     return val;
@@ -446,9 +437,6 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
 
     cpu = gic_get_current_cpu(s);
     if (offset < 0x100) {
-#ifdef NVIC
-        goto bad_reg;
-#else
         if (offset == 0) {
             s->enabled = (value & 1);
             DPRINTF("Distribution %sabled\n", s->enabled ? "En" : "Dis");
@@ -459,7 +447,6 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
         } else {
             goto bad_reg;
         }
-#endif
     } else if (offset < 0x180) {
         /* Interrupt Set Enable.  */
         irq = (offset - 0x100) * 8 + GIC_BASE_IRQ;
@@ -552,6 +539,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
         else if (irq < GIC_INTERNAL)
             value = ALL_CPU_MASK;
         s->irq_target[irq] = value & ALL_CPU_MASK;
+#endif
     } else if (offset < 0xf00) {
         /* Interrupt Configuration.  */
         irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
@@ -571,7 +559,6 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
                 GIC_CLEAR_TRIGGER(irq + i);
             }
         }
-#endif
     } else {
         /* 0xf00 is only handled for 32-bit writes.  */
         goto bad_reg;
@@ -593,14 +580,6 @@ static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
                             uint32_t value)
 {
     gic_state *s = (gic_state *)opaque;
-#ifdef NVIC
-    uint32_t addr;
-    addr = offset;
-    if (addr < 0x100 || (addr > 0xd00 && addr != 0xf00)) {
-        nvic_writel(s, addr, value);
-        return;
-    }
-#endif
     if (offset == 0xf00) {
         int cpu;
         int irq;
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 653c011..747e245 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -30,9 +30,16 @@ typedef struct {
         int64_t tick;
         QEMUTimer *timer;
     } systick;
+    MemoryRegion sysregmem;
+    MemoryRegion gic_iomem_alias;
+    MemoryRegion container;
     uint32_t num_irq;
 } nvic_state;
 
+static const uint8_t nvic_id[] = {
+    0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1
+};
+
 /* qemu timers run at 1GHz.   We want something closer to 1MHz.  */
 #define SYSTICK_SCALE 1000ULL
 
@@ -358,12 +365,54 @@ static void nvic_writel(void *opaque, uint32_t offset, uint32_t value)
     case 0xd38: /* Bus Fault Address.  */
     case 0xd3c: /* Aux Fault Status.  */
         goto bad_reg;
+    case 0xf00: /* Software Triggered Interrupt Register */
+        if ((value & 0x1ff) < s->num_irq) {
+            gic_set_pending_private(&s->gic, 0, value & 0x1ff);
+        }
+        break;
     default:
     bad_reg:
         hw_error("NVIC: Bad write offset 0x%x\n", offset);
     }
 }
 
+static uint64_t nvic_sysreg_read(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
+{
+    /* At the moment we only support the ID registers for byte/word access.
+     * This is not strictly correct as a few of the other registers also
+     * allow byte access.
+     */
+    uint32_t offset = addr;
+    if (offset >= 0xfe0) {
+        if (offset & 3) {
+            return 0;
+        }
+        return nvic_id[(offset - 0xfe0) >> 2];
+    }
+    if (size == 4) {
+        return nvic_readl(opaque, offset);
+    }
+    hw_error("NVIC: Bad read of size %d at offset 0x%x\n", size, offset);
+}
+
+static void nvic_sysreg_write(void *opaque, target_phys_addr_t addr,
+                              uint64_t value, unsigned size)
+{
+    uint32_t offset = addr;
+    if (size == 4) {
+        nvic_writel(opaque, offset, value);
+        return;
+    }
+    hw_error("NVIC: Bad write of size %d at offset 0x%x\n", size, offset);
+}
+
+static const MemoryRegionOps nvic_sysreg_ops = {
+    .read = nvic_sysreg_read,
+    .write = nvic_sysreg_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
 static const VMStateDescription vmstate_nvic = {
     .name = "armv7m_nvic",
     .version_id = 1,
@@ -399,7 +448,30 @@ static int armv7m_nvic_init(SysBusDevice *dev)
     /* The NVIC always has only one CPU */
     s->gic.num_cpu = 1;
     gic_init(&s->gic, s->num_irq);
-    memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->gic.iomem);
+    /* The NVIC and system controller register area looks like this:
+     *  0..0xff : system control registers, including systick
+     *  0x100..0xcff : GIC-like registers
+     *  0xd00..0xfff : system control registers
+     * We use overlaying to put the GIC like registers
+     * over the top of the system control register region.
+     */
+    memory_region_init(&s->container, "nvic", 0x1000);
+    /* The system register region goes at the bottom of the priority
+     * stack as it covers the whole page.
+     */
+    memory_region_init_io(&s->sysregmem, &nvic_sysreg_ops, s,
+                          "nvic_sysregs", 0x1000);
+    memory_region_add_subregion(&s->container, 0, &s->sysregmem);
+    /* Alias the GIC region so we can get only the section of it
+     * we need, and layer it on top of the system register region.
+     */
+    memory_region_init_alias(&s->gic_iomem_alias, "nvic-gic", &s->gic.iomem,
+                             0x100, 0xc00);
+    memory_region_add_subregion_overlap(&s->container, 0x100, &s->gic.iomem, 1);
+    /* Map the whole thing into system memory at the location required
+     * by the v7M architecture.
+     */
+    memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->container);
     s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s);
     return 0;
 }
-- 
1.7.1

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

* [Qemu-devel] [PATCH 07/16] hw/arm_gic: Add qdev property for GIC revision
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
                   ` (5 preceding siblings ...)
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 06/16] hw/armv7m_nvic: Use MemoryRegions for NVIC specific registers Peter Maydell
@ 2012-06-19 13:31 ` Peter Maydell
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 08/16] hw/arm_gic: Make CPU target registers RAZ/WI on uniprocessor Peter Maydell
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:31 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

GIC behaviour can be different between revision 1 and
2 of the architectural GIC specification; we also have
to handle the legacy 11MPCore GIC, which is different
again in some places. Introduce a qdev property so we
can behave appropriately.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/a15mpcore.c   |    1 +
 hw/arm11mpcore.c |    2 ++
 hw/arm_gic.c     |   10 ++++++++++
 hw/armv7m_nvic.c |    2 ++
 4 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
index 5a7b365..fc0a02a 100644
--- a/hw/a15mpcore.c
+++ b/hw/a15mpcore.c
@@ -44,6 +44,7 @@ static int a15mp_priv_init(SysBusDevice *dev)
     s->gic = qdev_create(NULL, "arm_gic");
     qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
     qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
+    qdev_prop_set_uint32(s->gic, "revision", 2);
     qdev_init_nofail(s->gic);
     busdev = sysbus_from_qdev(s->gic);
 
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index c528d7a..1bff3d3 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -123,6 +123,8 @@ static int mpcore_priv_init(SysBusDevice *dev)
     s->gic = qdev_create(NULL, "arm_gic");
     qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
     qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
+    /* Request the legacy 11MPCore GIC behaviour: */
+    qdev_prop_set_uint32(s->gic, "revision", 0);
     qdev_init_nofail(s->gic);
 
     /* Pass through outbound IRQ lines from the GIC */
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 2ec10ce..ad72ac6 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -119,8 +119,13 @@ typedef struct gic_state
     struct gic_state *backref[NCPU];
     MemoryRegion cpuiomem[NCPU+1]; /* CPU interfaces */
     uint32_t num_irq;
+    uint32_t revision;
 } gic_state;
 
+/* The special cases for the revision property: */
+#define REV_11MPCORE 0
+#define REV_NVIC 0xffffffff
+
 static inline int gic_get_current_cpu(gic_state *s)
 {
     if (s->num_cpu > 1) {
@@ -880,6 +885,11 @@ static int arm_gic_init(SysBusDevice *dev)
 static Property arm_gic_properties[] = {
     DEFINE_PROP_UINT32("num-cpu", gic_state, num_cpu, 1),
     DEFINE_PROP_UINT32("num-irq", gic_state, num_irq, 32),
+    /* Revision can be 1 or 2 for GIC architecture specification
+     * versions 1 or 2, or 0 to indicate the legacy 11MPCore GIC.
+     * (Internally, 0xffffffff also indicates "not a GIC but an NVIC".)
+     */
+    DEFINE_PROP_UINT32("revision", gic_state, revision, 1),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 747e245..4c130f1 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -447,6 +447,8 @@ static int armv7m_nvic_init(SysBusDevice *dev)
 
     /* The NVIC always has only one CPU */
     s->gic.num_cpu = 1;
+    /* Tell the common code we're an NVIC */
+    s->gic.revision = 0xffffffff;
     gic_init(&s->gic, s->num_irq);
     /* The NVIC and system controller register area looks like this:
      *  0..0xff : system control registers, including systick
-- 
1.7.1

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

* [Qemu-devel] [PATCH 08/16] hw/arm_gic: Make CPU target registers RAZ/WI on uniprocessor
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
                   ` (6 preceding siblings ...)
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 07/16] hw/arm_gic: Add qdev property for GIC revision Peter Maydell
@ 2012-06-19 13:31 ` Peter Maydell
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 09/16] hw/arm_gic.c: Make NVIC interrupt numbering a runtime setting Peter Maydell
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:31 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

The GIC spec says that the CPU target registers should RAZ/WI
for uniprocessor implementations. Implement this, which also
conveniently lets us drop an NVIC ifdef.

Annoyingly, the 11MPCore's GIC is the odd one out, since
it always has these registers, even in uniprocessor configs.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm_gic.c |   56 +++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index ad72ac6..a6e2431 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -86,11 +86,7 @@ typedef struct gic_irq_state
 #define GIC_GET_PRIORITY(irq, cpu) (((irq) < GIC_INTERNAL) ?            \
                                     s->priority1[irq][cpu] :            \
                                     s->priority2[(irq) - GIC_INTERNAL])
-#ifdef NVIC
-#define GIC_TARGET(irq) 1
-#else
 #define GIC_TARGET(irq) s->irq_target[irq]
-#endif
 
 typedef struct gic_state
 {
@@ -377,18 +373,22 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
         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 >= s->num_irq)
-            goto bad_reg;
-        if (irq >= 29 && irq <= 31) {
-            res = cm;
+        if (s->num_cpu == 1 && s->revision != REV_11MPCORE) {
+            /* For uniprocessor GICs these RAZ/WI */
+            res = 0;
         } else {
-            res = GIC_TARGET(irq);
+            irq = (offset - 0x800) + GIC_BASE_IRQ;
+            if (irq >= s->num_irq) {
+                goto bad_reg;
+            }
+            if (irq >= 29 && irq <= 31) {
+                res = cm;
+            } else {
+                res = GIC_TARGET(irq);
+            }
         }
-#endif
     } else if (offset < 0xf00) {
         /* Interrupt Configuration.  */
         irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ;
@@ -533,18 +533,22 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
         } else {
             s->priority2[irq - GIC_INTERNAL] = value;
         }
-#ifndef NVIC
     } else if (offset < 0xc00) {
-        /* Interrupt CPU Target.  */
-        irq = (offset - 0x800) + GIC_BASE_IRQ;
-        if (irq >= s->num_irq)
-            goto bad_reg;
-        if (irq < 29)
-            value = 0;
-        else if (irq < GIC_INTERNAL)
-            value = ALL_CPU_MASK;
-        s->irq_target[irq] = value & ALL_CPU_MASK;
-#endif
+        /* Interrupt CPU Target. RAZ/WI on uniprocessor GICs, with the
+         * annoying exception of the 11MPCore's GIC.
+         */
+        if (s->num_cpu != 1 || s->revision == REV_11MPCORE) {
+            irq = (offset - 0x800) + GIC_BASE_IRQ;
+            if (irq >= s->num_irq) {
+                goto bad_reg;
+            }
+            if (irq < 29) {
+                value = 0;
+            } else if (irq < GIC_INTERNAL) {
+                value = ALL_CPU_MASK;
+            }
+            s->irq_target[irq] = value & ALL_CPU_MASK;
+        }
     } else if (offset < 0xf00) {
         /* Interrupt Configuration.  */
         irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
@@ -733,6 +737,12 @@ static void gic_reset(DeviceState *dev)
         GIC_SET_ENABLED(i, ALL_CPU_MASK);
         GIC_SET_TRIGGER(i);
     }
+    if (s->num_cpu == 1) {
+        /* For uniprocessor GICs all interrupts always target the sole CPU */
+        for (i = 0; i < GIC_MAXIRQ; i++) {
+            s->irq_target[i] = 1;
+        }
+    }
     s->enabled = 0;
 }
 
-- 
1.7.1

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

* [Qemu-devel] [PATCH 09/16] hw/arm_gic.c: Make NVIC interrupt numbering a runtime setting
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
                   ` (7 preceding siblings ...)
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 08/16] hw/arm_gic: Make CPU target registers RAZ/WI on uniprocessor Peter Maydell
@ 2012-06-19 13:31 ` Peter Maydell
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 10/16] hw/arm_gic: Move CPU interface memory region setup into arm_gic_init Peter Maydell
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:31 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Make the minor tweaks to interrupt numbering used by the NVIC
a runtime setting rather than a compile time one, so we can
drop more NVIC ifdefs.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm_gic.c |   12 ++++--------
 1 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index a6e2431..c288bc5 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -36,13 +36,9 @@ do { printf("arm_gic: " fmt , ## __VA_ARGS__); } while (0)
 #define DPRINTF(fmt, ...) do {} while(0)
 #endif
 
-#ifdef NVIC
 /* The NVIC has 16 internal vectors.  However these are not exposed
    through the normal GIC interface.  */
-#define GIC_BASE_IRQ    32
-#else
-#define GIC_BASE_IRQ    0
-#endif
+#define GIC_BASE_IRQ ((s->revision == REV_NVIC) ? 32 : 0)
 
 static const uint8_t gic_id[] = {
     0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1
@@ -839,7 +835,6 @@ static void gic_init(gic_state *s, int num_irq)
     }
 
     i = s->num_irq - GIC_INTERNAL;
-#ifndef NVIC
     /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
      * GPIO array layout is thus:
      *  [0..N-1] SPIs
@@ -847,8 +842,9 @@ static void gic_init(gic_state *s, int num_irq)
      *  [N+32..N+63] PPIs for CPU 1
      *   ...
      */
-    i += (GIC_INTERNAL * s->num_cpu);
-#endif
+    if (s->revision != REV_NVIC) {
+        i += (GIC_INTERNAL * s->num_cpu);
+    }
     qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, i);
     for (i = 0; i < NUM_CPU(s); i++) {
         sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
-- 
1.7.1

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

* [Qemu-devel] [PATCH 10/16] hw/arm_gic: Move CPU interface memory region setup into arm_gic_init
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
                   ` (8 preceding siblings ...)
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 09/16] hw/arm_gic.c: Make NVIC interrupt numbering a runtime setting Peter Maydell
@ 2012-06-19 13:31 ` Peter Maydell
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 11/16] hw/armv7m_nvic: Make the NVIC a freestanding class Peter Maydell
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:31 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Remove more NVIC ifdefs by moving the code to setup the CPU interface
memory regions into the GIC specific arm_gic_init() function rather
than the gic_init() function. Rename the latter to more closely
reflect what it's now actually doing.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm_gic.c     |   26 +++++++++++++-------------
 hw/armv7m_nvic.c |    2 +-
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index c288bc5..ad5ab3c 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -812,7 +812,7 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void gic_init(gic_state *s, int num_irq)
+static void gic_init_irqs_and_distributor(gic_state *s, int num_irq)
 {
     int i;
 
@@ -850,7 +850,19 @@ static void gic_init(gic_state *s, int num_irq)
         sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
     }
     memory_region_init_io(&s->iomem, &gic_dist_ops, s, "gic_dist", 0x1000);
+
+    register_savevm(NULL, "arm_gic", -1, 3, gic_save, gic_load, s);
+}
+
 #ifndef NVIC
+
+static int arm_gic_init(SysBusDevice *dev)
+{
+    /* Device instance init function for the GIC sysbus device */
+    int i;
+    gic_state *s = FROM_SYSBUS(gic_state, dev);
+    gic_init_irqs_and_distributor(s, s->num_irq);
+
     /* Memory regions for the CPU interfaces (NVIC doesn't have these):
      * a region for "CPU interface for this core", then a region for
      * "CPU interface for core 0", "for core 1", ...
@@ -866,19 +878,7 @@ static void gic_init(gic_state *s, int num_irq)
         memory_region_init_io(&s->cpuiomem[i+1], &gic_cpu_ops, &s->backref[i],
                               "gic_cpu", 0x100);
     }
-#endif
-
-    register_savevm(NULL, "arm_gic", -1, 3, gic_save, gic_load, s);
-}
-
-#ifndef NVIC
 
-static int arm_gic_init(SysBusDevice *dev)
-{
-    /* Device instance init function for the GIC sysbus device */
-    int i;
-    gic_state *s = FROM_SYSBUS(gic_state, dev);
-    gic_init(s, s->num_irq);
     /* Distributor */
     sysbus_init_mmio(dev, &s->iomem);
     /* cpu interfaces (one for "current cpu" plus one per cpu) */
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 4c130f1..031a7fd 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -449,7 +449,7 @@ static int armv7m_nvic_init(SysBusDevice *dev)
     s->gic.num_cpu = 1;
     /* Tell the common code we're an NVIC */
     s->gic.revision = 0xffffffff;
-    gic_init(&s->gic, s->num_irq);
+    gic_init_irqs_and_distributor(&s->gic, s->num_irq);
     /* The NVIC and system controller register area looks like this:
      *  0..0xff : system control registers, including systick
      *  0x100..0xcff : GIC-like registers
-- 
1.7.1

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

* [Qemu-devel] [PATCH 11/16] hw/armv7m_nvic: Make the NVIC a freestanding class
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
                   ` (9 preceding siblings ...)
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 10/16] hw/arm_gic: Move CPU interface memory region setup into arm_gic_init Peter Maydell
@ 2012-06-19 13:31 ` Peter Maydell
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 12/16] hw/omap.h: Drop broken MEM_VERBOSE tracing Peter Maydell
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:31 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Rearrange the GIC and NVIC so both are straightforward
subclasses of a common class, rather than having the NVIC
source file textually include arm_gic.c.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/Makefile.objs  |    2 +-
 hw/arm_gic.c          |  241 +++----------------------------------------------
 hw/arm_gic_common.c   |  184 +++++++++++++++++++++++++++++++++++++
 hw/arm_gic_internal.h |  136 ++++++++++++++++++++++++++++
 hw/armv7m_nvic.c      |   48 ++++++++---
 5 files changed, 371 insertions(+), 240 deletions(-)
 create mode 100644 hw/arm_gic_common.c
 create mode 100644 hw/arm_gic_internal.h

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index a0ff6a6..88ff47d 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -6,7 +6,7 @@ obj-y += cadence_uart.o
 obj-y += cadence_ttc.o
 obj-y += cadence_gem.o
 obj-y += xilinx_zynq.o zynq_slcr.o
-obj-y += arm_gic.o
+obj-y += arm_gic.o arm_gic_common.o
 obj-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
 obj-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o
 obj-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index ad5ab3c..ec22322 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -19,13 +19,7 @@
  */
 
 #include "sysbus.h"
-
-/* Maximum number of possible interrupts, determined by the GIC architecture */
-#define GIC_MAXIRQ 1020
-/* First 32 are private to each CPU (SGIs and PPIs). */
-#define GIC_INTERNAL 32
-/* Maximum number of possible CPU interfaces, determined by GIC architecture */
-#define NCPU 8
+#include "arm_gic_internal.h"
 
 //#define DEBUG_GIC
 
@@ -36,88 +30,12 @@ do { printf("arm_gic: " fmt , ## __VA_ARGS__); } while (0)
 #define DPRINTF(fmt, ...) do {} while(0)
 #endif
 
-/* The NVIC has 16 internal vectors.  However these are not exposed
-   through the normal GIC interface.  */
-#define GIC_BASE_IRQ ((s->revision == REV_NVIC) ? 32 : 0)
-
 static const uint8_t gic_id[] = {
     0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1
 };
 
-#define FROM_SYSBUSGIC(type, dev) \
-    DO_UPCAST(type, gic, FROM_SYSBUS(gic_state, dev))
-
-typedef struct gic_irq_state
-{
-    /* The enable bits are only banked for per-cpu interrupts.  */
-    unsigned enabled:NCPU;
-    unsigned pending:NCPU;
-    unsigned active:NCPU;
-    unsigned level:NCPU;
-    unsigned model:1; /* 0 = N:N, 1 = 1:N */
-    unsigned trigger:1; /* nonzero = edge triggered.  */
-} gic_irq_state;
-
-#define ALL_CPU_MASK ((unsigned)(((1 << NCPU) - 1)))
 #define NUM_CPU(s) ((s)->num_cpu)
 
-#define GIC_SET_ENABLED(irq, cm) s->irq_state[irq].enabled |= (cm)
-#define GIC_CLEAR_ENABLED(irq, cm) s->irq_state[irq].enabled &= ~(cm)
-#define GIC_TEST_ENABLED(irq, cm) ((s->irq_state[irq].enabled & (cm)) != 0)
-#define GIC_SET_PENDING(irq, cm) s->irq_state[irq].pending |= (cm)
-#define GIC_CLEAR_PENDING(irq, cm) s->irq_state[irq].pending &= ~(cm)
-#define GIC_TEST_PENDING(irq, cm) ((s->irq_state[irq].pending & (cm)) != 0)
-#define GIC_SET_ACTIVE(irq, cm) s->irq_state[irq].active |= (cm)
-#define GIC_CLEAR_ACTIVE(irq, cm) s->irq_state[irq].active &= ~(cm)
-#define GIC_TEST_ACTIVE(irq, cm) ((s->irq_state[irq].active & (cm)) != 0)
-#define GIC_SET_MODEL(irq) s->irq_state[irq].model = 1
-#define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = 0
-#define GIC_TEST_MODEL(irq) s->irq_state[irq].model
-#define GIC_SET_LEVEL(irq, cm) s->irq_state[irq].level = (cm)
-#define GIC_CLEAR_LEVEL(irq, cm) s->irq_state[irq].level &= ~(cm)
-#define GIC_TEST_LEVEL(irq, cm) ((s->irq_state[irq].level & (cm)) != 0)
-#define GIC_SET_TRIGGER(irq) s->irq_state[irq].trigger = 1
-#define GIC_CLEAR_TRIGGER(irq) s->irq_state[irq].trigger = 0
-#define GIC_TEST_TRIGGER(irq) s->irq_state[irq].trigger
-#define GIC_GET_PRIORITY(irq, cpu) (((irq) < GIC_INTERNAL) ?            \
-                                    s->priority1[irq][cpu] :            \
-                                    s->priority2[(irq) - GIC_INTERNAL])
-#define GIC_TARGET(irq) s->irq_target[irq]
-
-typedef struct gic_state
-{
-    SysBusDevice busdev;
-    qemu_irq parent_irq[NCPU];
-    int enabled;
-    int cpu_enabled[NCPU];
-
-    gic_irq_state irq_state[GIC_MAXIRQ];
-    int irq_target[GIC_MAXIRQ];
-    int priority1[GIC_INTERNAL][NCPU];
-    int priority2[GIC_MAXIRQ - GIC_INTERNAL];
-    int last_active[GIC_MAXIRQ][NCPU];
-
-    int priority_mask[NCPU];
-    int running_irq[NCPU];
-    int running_priority[NCPU];
-    int current_pending[NCPU];
-
-    uint32_t num_cpu;
-
-    MemoryRegion iomem; /* Distributor */
-    /* This is just so we can have an opaque pointer which identifies
-     * both this GIC and which CPU interface we should be accessing.
-     */
-    struct gic_state *backref[NCPU];
-    MemoryRegion cpuiomem[NCPU+1]; /* CPU interfaces */
-    uint32_t num_irq;
-    uint32_t revision;
-} gic_state;
-
-/* The special cases for the revision property: */
-#define REV_11MPCORE 0
-#define REV_NVIC 0xffffffff
-
 static inline int gic_get_current_cpu(gic_state *s)
 {
     if (s->num_cpu > 1) {
@@ -128,7 +46,7 @@ static inline int gic_get_current_cpu(gic_state *s)
 
 /* TODO: Many places that call this routine could be optimized.  */
 /* Update interrupt status after enabled or pending bits have been changed.  */
-static void gic_update(gic_state *s)
+void gic_update(gic_state *s)
 {
     int best_irq;
     int best_prio;
@@ -166,8 +84,7 @@ static void gic_update(gic_state *s)
     }
 }
 
-#ifdef NVIC
-static void gic_set_pending_private(gic_state *s, int cpu, int irq)
+void gic_set_pending_private(gic_state *s, int cpu, int irq)
 {
     int cm = 1 << cpu;
 
@@ -178,7 +95,6 @@ static void gic_set_pending_private(gic_state *s, int cpu, int irq)
     GIC_SET_PENDING(irq, cm);
     gic_update(s);
 }
-#endif
 
 /* Process a change in an external IRQ input.  */
 static void gic_set_irq(void *opaque, int irq, int level)
@@ -232,7 +148,7 @@ static void gic_set_running_irq(gic_state *s, int cpu, int irq)
     gic_update(s);
 }
 
-static uint32_t gic_acknowledge_irq(gic_state *s, int cpu)
+uint32_t gic_acknowledge_irq(gic_state *s, int cpu)
 {
     int new_irq;
     int cm = 1 << cpu;
@@ -251,7 +167,7 @@ static uint32_t gic_acknowledge_irq(gic_state *s, int cpu)
     return new_irq;
 }
 
-static void gic_complete_irq(gic_state * s, int cpu, int irq)
+void gic_complete_irq(gic_state *s, int cpu, int irq)
 {
     int update = 0;
     int cm = 1 << cpu;
@@ -623,7 +539,6 @@ static const MemoryRegionOps gic_dist_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-#ifndef NVIC
 static uint32_t gic_cpu_read(gic_state *s, int cpu, int offset)
 {
     switch (offset) {
@@ -715,124 +630,10 @@ static const MemoryRegionOps gic_cpu_ops = {
     .write = gic_do_cpu_write,
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
-#endif
 
-static void gic_reset(DeviceState *dev)
+void gic_init_irqs_and_distributor(gic_state *s, int num_irq)
 {
-    gic_state *s = FROM_SYSBUS(gic_state, sysbus_from_qdev(dev));
-    int i;
-    memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state));
-    for (i = 0 ; i < NUM_CPU(s); i++) {
-        s->priority_mask[i] = 0xf0;
-        s->current_pending[i] = 1023;
-        s->running_irq[i] = 1023;
-        s->running_priority[i] = 0x100;
-        s->cpu_enabled[i] = 0;
-    }
-    for (i = 0; i < 16; i++) {
-        GIC_SET_ENABLED(i, ALL_CPU_MASK);
-        GIC_SET_TRIGGER(i);
-    }
-    if (s->num_cpu == 1) {
-        /* For uniprocessor GICs all interrupts always target the sole CPU */
-        for (i = 0; i < GIC_MAXIRQ; i++) {
-            s->irq_target[i] = 1;
-        }
-    }
-    s->enabled = 0;
-}
-
-static void gic_save(QEMUFile *f, void *opaque)
-{
-    gic_state *s = (gic_state *)opaque;
-    int i;
-    int j;
-
-    qemu_put_be32(f, s->enabled);
-    for (i = 0; i < NUM_CPU(s); i++) {
-        qemu_put_be32(f, s->cpu_enabled[i]);
-        for (j = 0; j < GIC_INTERNAL; j++)
-            qemu_put_be32(f, s->priority1[j][i]);
-        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 < s->num_irq - GIC_INTERNAL; i++) {
-        qemu_put_be32(f, s->priority2[i]);
-    }
-    for (i = 0; i < s->num_irq; i++) {
-        qemu_put_be32(f, s->irq_target[i]);
-        qemu_put_byte(f, s->irq_state[i].enabled);
-        qemu_put_byte(f, s->irq_state[i].pending);
-        qemu_put_byte(f, s->irq_state[i].active);
-        qemu_put_byte(f, s->irq_state[i].level);
-        qemu_put_byte(f, s->irq_state[i].model);
-        qemu_put_byte(f, s->irq_state[i].trigger);
-    }
-}
-
-static int gic_load(QEMUFile *f, void *opaque, int version_id)
-{
-    gic_state *s = (gic_state *)opaque;
     int i;
-    int j;
-
-    if (version_id != 3) {
-        return -EINVAL;
-    }
-
-    s->enabled = qemu_get_be32(f);
-    for (i = 0; i < NUM_CPU(s); i++) {
-        s->cpu_enabled[i] = qemu_get_be32(f);
-        for (j = 0; j < GIC_INTERNAL; j++)
-            s->priority1[j][i] = qemu_get_be32(f);
-        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 < s->num_irq - GIC_INTERNAL; i++) {
-        s->priority2[i] = qemu_get_be32(f);
-    }
-    for (i = 0; i < s->num_irq; i++) {
-        s->irq_target[i] = qemu_get_be32(f);
-        s->irq_state[i].enabled = qemu_get_byte(f);
-        s->irq_state[i].pending = qemu_get_byte(f);
-        s->irq_state[i].active = qemu_get_byte(f);
-        s->irq_state[i].level = qemu_get_byte(f);
-        s->irq_state[i].model = qemu_get_byte(f);
-        s->irq_state[i].trigger = qemu_get_byte(f);
-    }
-
-    return 0;
-}
-
-static void gic_init_irqs_and_distributor(gic_state *s, int num_irq)
-{
-    int i;
-
-    if (s->num_cpu > NCPU) {
-        hw_error("requested %u CPUs exceeds GIC maximum %d\n",
-                 s->num_cpu, NCPU);
-    }
-    s->num_irq = num_irq + GIC_BASE_IRQ;
-    if (s->num_irq > GIC_MAXIRQ) {
-        hw_error("requested %u interrupt lines exceeds GIC maximum %d\n",
-                 num_irq, GIC_MAXIRQ);
-    }
-    /* ITLinesNumber is represented as (N / 32) - 1 (see
-     * gic_dist_readb) so this is an implementation imposed
-     * restriction, not an architectural one:
-     */
-    if (s->num_irq < 32 || (s->num_irq % 32)) {
-        hw_error("%d interrupt lines unsupported: not divisible by 32\n",
-                 num_irq);
-    }
 
     i = s->num_irq - GIC_INTERNAL;
     /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
@@ -850,17 +651,17 @@ static void gic_init_irqs_and_distributor(gic_state *s, int num_irq)
         sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
     }
     memory_region_init_io(&s->iomem, &gic_dist_ops, s, "gic_dist", 0x1000);
-
-    register_savevm(NULL, "arm_gic", -1, 3, gic_save, gic_load, s);
 }
 
-#ifndef NVIC
-
 static int arm_gic_init(SysBusDevice *dev)
 {
     /* Device instance init function for the GIC sysbus device */
     int i;
     gic_state *s = FROM_SYSBUS(gic_state, dev);
+    ARMGICClass *agc = ARM_GIC_GET_CLASS(s);
+
+    agc->parent_init(dev);
+
     gic_init_irqs_and_distributor(s, s->num_irq);
 
     /* Memory regions for the CPU interfaces (NVIC doesn't have these):
@@ -878,7 +679,6 @@ static int arm_gic_init(SysBusDevice *dev)
         memory_region_init_io(&s->cpuiomem[i+1], &gic_cpu_ops, &s->backref[i],
                               "gic_cpu", 0x100);
     }
-
     /* Distributor */
     sysbus_init_mmio(dev, &s->iomem);
     /* cpu interfaces (one for "current cpu" plus one per cpu) */
@@ -888,30 +688,19 @@ static int arm_gic_init(SysBusDevice *dev)
     return 0;
 }
 
-static Property arm_gic_properties[] = {
-    DEFINE_PROP_UINT32("num-cpu", gic_state, num_cpu, 1),
-    DEFINE_PROP_UINT32("num-irq", gic_state, num_irq, 32),
-    /* Revision can be 1 or 2 for GIC architecture specification
-     * versions 1 or 2, or 0 to indicate the legacy 11MPCore GIC.
-     * (Internally, 0xffffffff also indicates "not a GIC but an NVIC".)
-     */
-    DEFINE_PROP_UINT32("revision", gic_state, revision, 1),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
 static void arm_gic_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+    ARMGICClass *agc = ARM_GIC_CLASS(klass);
+    agc->parent_init = sbc->init;
     sbc->init = arm_gic_init;
-    dc->props = arm_gic_properties;
-    dc->reset = gic_reset;
     dc->no_user = 1;
 }
 
 static TypeInfo arm_gic_info = {
-    .name = "arm_gic",
-    .parent = TYPE_SYS_BUS_DEVICE,
+    .name = TYPE_ARM_GIC,
+    .parent = TYPE_ARM_GIC_COMMON,
     .instance_size = sizeof(gic_state),
     .class_init = arm_gic_class_init,
 };
@@ -922,5 +711,3 @@ static void arm_gic_register_types(void)
 }
 
 type_init(arm_gic_register_types)
-
-#endif
diff --git a/hw/arm_gic_common.c b/hw/arm_gic_common.c
new file mode 100644
index 0000000..360e782
--- /dev/null
+++ b/hw/arm_gic_common.c
@@ -0,0 +1,184 @@
+/*
+ * ARM GIC support - common bits of emulated and KVM kernel model
+ *
+ * Copyright (c) 2012 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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 "arm_gic_internal.h"
+
+static void gic_save(QEMUFile *f, void *opaque)
+{
+    gic_state *s = (gic_state *)opaque;
+    int i;
+    int j;
+
+    qemu_put_be32(f, s->enabled);
+    for (i = 0; i < s->num_cpu; i++) {
+        qemu_put_be32(f, s->cpu_enabled[i]);
+        for (j = 0; j < GIC_INTERNAL; j++) {
+            qemu_put_be32(f, s->priority1[j][i]);
+        }
+        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 < s->num_irq - GIC_INTERNAL; i++) {
+        qemu_put_be32(f, s->priority2[i]);
+    }
+    for (i = 0; i < s->num_irq; i++) {
+        qemu_put_be32(f, s->irq_target[i]);
+        qemu_put_byte(f, s->irq_state[i].enabled);
+        qemu_put_byte(f, s->irq_state[i].pending);
+        qemu_put_byte(f, s->irq_state[i].active);
+        qemu_put_byte(f, s->irq_state[i].level);
+        qemu_put_byte(f, s->irq_state[i].model);
+        qemu_put_byte(f, s->irq_state[i].trigger);
+    }
+}
+
+static int gic_load(QEMUFile *f, void *opaque, int version_id)
+{
+    gic_state *s = (gic_state *)opaque;
+    int i;
+    int j;
+
+    if (version_id != 3) {
+        return -EINVAL;
+    }
+
+    s->enabled = qemu_get_be32(f);
+    for (i = 0; i < s->num_cpu; i++) {
+        s->cpu_enabled[i] = qemu_get_be32(f);
+        for (j = 0; j < GIC_INTERNAL; j++) {
+            s->priority1[j][i] = qemu_get_be32(f);
+        }
+        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 < s->num_irq - GIC_INTERNAL; i++) {
+        s->priority2[i] = qemu_get_be32(f);
+    }
+    for (i = 0; i < s->num_irq; i++) {
+        s->irq_target[i] = qemu_get_be32(f);
+        s->irq_state[i].enabled = qemu_get_byte(f);
+        s->irq_state[i].pending = qemu_get_byte(f);
+        s->irq_state[i].active = qemu_get_byte(f);
+        s->irq_state[i].level = qemu_get_byte(f);
+        s->irq_state[i].model = qemu_get_byte(f);
+        s->irq_state[i].trigger = qemu_get_byte(f);
+    }
+
+    return 0;
+}
+
+static int arm_gic_common_init(SysBusDevice *dev)
+{
+    gic_state *s = FROM_SYSBUS(gic_state, dev);
+    int num_irq = s->num_irq;
+
+    if (s->num_cpu > NCPU) {
+        hw_error("requested %u CPUs exceeds GIC maximum %d\n",
+                 s->num_cpu, NCPU);
+    }
+    s->num_irq += GIC_BASE_IRQ;
+    if (s->num_irq > GIC_MAXIRQ) {
+        hw_error("requested %u interrupt lines exceeds GIC maximum %d\n",
+                 num_irq, GIC_MAXIRQ);
+    }
+    /* ITLinesNumber is represented as (N / 32) - 1 (see
+     * gic_dist_readb) so this is an implementation imposed
+     * restriction, not an architectural one:
+     */
+    if (s->num_irq < 32 || (s->num_irq % 32)) {
+        hw_error("%d interrupt lines unsupported: not divisible by 32\n",
+                 num_irq);
+    }
+
+    register_savevm(NULL, "arm_gic", -1, 3, gic_save, gic_load, s);
+    return 0;
+}
+
+static void arm_gic_common_reset(DeviceState *dev)
+{
+    gic_state *s = FROM_SYSBUS(gic_state, sysbus_from_qdev(dev));
+    int i;
+    memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state));
+    for (i = 0 ; i < s->num_cpu; i++) {
+        s->priority_mask[i] = 0xf0;
+        s->current_pending[i] = 1023;
+        s->running_irq[i] = 1023;
+        s->running_priority[i] = 0x100;
+        s->cpu_enabled[i] = 0;
+    }
+    for (i = 0; i < 16; i++) {
+        GIC_SET_ENABLED(i, ALL_CPU_MASK);
+        GIC_SET_TRIGGER(i);
+    }
+    if (s->num_cpu == 1) {
+        /* For uniprocessor GICs all interrupts always target the sole CPU */
+        for (i = 0; i < GIC_MAXIRQ; i++) {
+            s->irq_target[i] = 1;
+        }
+    }
+    s->enabled = 0;
+}
+
+static Property arm_gic_common_properties[] = {
+    DEFINE_PROP_UINT32("num-cpu", gic_state, num_cpu, 1),
+    DEFINE_PROP_UINT32("num-irq", gic_state, num_irq, 32),
+    /* Revision can be 1 or 2 for GIC architecture specification
+     * versions 1 or 2, or 0 to indicate the legacy 11MPCore GIC.
+     * (Internally, 0xffffffff also indicates "not a GIC but an NVIC".)
+     */
+    DEFINE_PROP_UINT32("revision", gic_state, revision, 1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void arm_gic_common_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    dc->reset = arm_gic_common_reset;
+    dc->props = arm_gic_common_properties;
+    dc->no_user = 1;
+    sc->init = arm_gic_common_init;
+}
+
+static TypeInfo arm_gic_common_type = {
+    .name = TYPE_ARM_GIC_COMMON,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(gic_state),
+    .class_size = sizeof(ARMGICCommonClass),
+    .class_init = arm_gic_common_class_init,
+    .abstract = true,
+};
+
+static void register_types(void)
+{
+    type_register_static(&arm_gic_common_type);
+}
+
+type_init(register_types)
diff --git a/hw/arm_gic_internal.h b/hw/arm_gic_internal.h
new file mode 100644
index 0000000..db4fad5
--- /dev/null
+++ b/hw/arm_gic_internal.h
@@ -0,0 +1,136 @@
+/*
+ * ARM GIC support - internal interfaces
+ *
+ * Copyright (c) 2012 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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/>.
+ */
+
+#ifndef QEMU_ARM_GIC_INTERNAL_H
+#define QEMU_ARM_GIC_INTERNAL_H
+
+#include "sysbus.h"
+
+/* Maximum number of possible interrupts, determined by the GIC architecture */
+#define GIC_MAXIRQ 1020
+/* First 32 are private to each CPU (SGIs and PPIs). */
+#define GIC_INTERNAL 32
+/* Maximum number of possible CPU interfaces, determined by GIC architecture */
+#define NCPU 8
+
+#define ALL_CPU_MASK ((unsigned)(((1 << NCPU) - 1)))
+
+/* The NVIC has 16 internal vectors.  However these are not exposed
+   through the normal GIC interface.  */
+#define GIC_BASE_IRQ ((s->revision == REV_NVIC) ? 32 : 0)
+
+#define GIC_SET_ENABLED(irq, cm) s->irq_state[irq].enabled |= (cm)
+#define GIC_CLEAR_ENABLED(irq, cm) s->irq_state[irq].enabled &= ~(cm)
+#define GIC_TEST_ENABLED(irq, cm) ((s->irq_state[irq].enabled & (cm)) != 0)
+#define GIC_SET_PENDING(irq, cm) s->irq_state[irq].pending |= (cm)
+#define GIC_CLEAR_PENDING(irq, cm) s->irq_state[irq].pending &= ~(cm)
+#define GIC_TEST_PENDING(irq, cm) ((s->irq_state[irq].pending & (cm)) != 0)
+#define GIC_SET_ACTIVE(irq, cm) s->irq_state[irq].active |= (cm)
+#define GIC_CLEAR_ACTIVE(irq, cm) s->irq_state[irq].active &= ~(cm)
+#define GIC_TEST_ACTIVE(irq, cm) ((s->irq_state[irq].active & (cm)) != 0)
+#define GIC_SET_MODEL(irq) s->irq_state[irq].model = 1
+#define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = 0
+#define GIC_TEST_MODEL(irq) s->irq_state[irq].model
+#define GIC_SET_LEVEL(irq, cm) s->irq_state[irq].level = (cm)
+#define GIC_CLEAR_LEVEL(irq, cm) s->irq_state[irq].level &= ~(cm)
+#define GIC_TEST_LEVEL(irq, cm) ((s->irq_state[irq].level & (cm)) != 0)
+#define GIC_SET_TRIGGER(irq) s->irq_state[irq].trigger = 1
+#define GIC_CLEAR_TRIGGER(irq) s->irq_state[irq].trigger = 0
+#define GIC_TEST_TRIGGER(irq) s->irq_state[irq].trigger
+#define GIC_GET_PRIORITY(irq, cpu) (((irq) < GIC_INTERNAL) ?            \
+                                    s->priority1[irq][cpu] :            \
+                                    s->priority2[(irq) - GIC_INTERNAL])
+#define GIC_TARGET(irq) s->irq_target[irq]
+
+typedef struct gic_irq_state {
+    /* The enable bits are only banked for per-cpu interrupts.  */
+    unsigned enabled:NCPU;
+    unsigned pending:NCPU;
+    unsigned active:NCPU;
+    unsigned level:NCPU;
+    unsigned model:1; /* 0 = N:N, 1 = 1:N */
+    unsigned trigger:1; /* nonzero = edge triggered.  */
+} gic_irq_state;
+
+typedef struct gic_state {
+    SysBusDevice busdev;
+    qemu_irq parent_irq[NCPU];
+    int enabled;
+    int cpu_enabled[NCPU];
+
+    gic_irq_state irq_state[GIC_MAXIRQ];
+    int irq_target[GIC_MAXIRQ];
+    int priority1[GIC_INTERNAL][NCPU];
+    int priority2[GIC_MAXIRQ - GIC_INTERNAL];
+    int last_active[GIC_MAXIRQ][NCPU];
+
+    int priority_mask[NCPU];
+    int running_irq[NCPU];
+    int running_priority[NCPU];
+    int current_pending[NCPU];
+
+    uint32_t num_cpu;
+
+    MemoryRegion iomem; /* Distributor */
+    /* This is just so we can have an opaque pointer which identifies
+     * both this GIC and which CPU interface we should be accessing.
+     */
+    struct gic_state *backref[NCPU];
+    MemoryRegion cpuiomem[NCPU+1]; /* CPU interfaces */
+    uint32_t num_irq;
+    uint32_t revision;
+} gic_state;
+
+/* The special cases for the revision property: */
+#define REV_11MPCORE 0
+#define REV_NVIC 0xffffffff
+
+void gic_set_pending_private(gic_state *s, int cpu, int irq);
+uint32_t gic_acknowledge_irq(gic_state *s, int cpu);
+void gic_complete_irq(gic_state *s, int cpu, int irq);
+void gic_update(gic_state *s);
+void gic_init_irqs_and_distributor(gic_state *s, int num_irq);
+
+#define TYPE_ARM_GIC_COMMON "arm_gic_common"
+#define ARM_GIC_COMMON(obj) \
+     OBJECT_CHECK(gic_state, (obj), TYPE_ARM_GIC_COMMON)
+#define ARM_GIC_COMMON_CLASS(klass) \
+     OBJECT_CLASS_CHECK(ARMGICCommonClass, (klass), TYPE_ARM_GIC_COMMON)
+#define ARM_GIC_COMMON_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(ARMGICCommonClass, (obj), TYPE_ARM_GIC_COMMON)
+
+typedef struct ARMGICCommonClass {
+    SysBusDeviceClass parent_class;
+} ARMGICCommonClass;
+
+#define TYPE_ARM_GIC "arm_gic"
+#define ARM_GIC(obj) \
+     OBJECT_CHECK(gic_state, (obj), TYPE_ARM_GIC)
+#define ARM_GIC_CLASS(klass) \
+     OBJECT_CLASS_CHECK(ARMGICClass, (klass), TYPE_ARM_GIC)
+#define ARM_GIC_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(ARMGICClass, (obj), TYPE_ARM_GIC)
+
+typedef struct ARMGICClass {
+    ARMGICCommonClass parent_class;
+    int (*parent_init)(SysBusDevice *dev);
+} ARMGICClass;
+
+#endif /* !QEMU_ARM_GIC_INTERNAL_H */
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 031a7fd..4867c1d 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -14,13 +14,7 @@
 #include "qemu-timer.h"
 #include "arm-misc.h"
 #include "exec-memory.h"
-
-#define NVIC 1
-
-static uint32_t nvic_readl(void *opaque, uint32_t offset);
-static void nvic_writel(void *opaque, uint32_t offset, uint32_t value);
-
-#include "arm_gic.c"
+#include "arm_gic_internal.h"
 
 typedef struct {
     gic_state gic;
@@ -36,6 +30,28 @@ typedef struct {
     uint32_t num_irq;
 } nvic_state;
 
+#define TYPE_NVIC "armv7m_nvic"
+/**
+ * NVICClass:
+ * @parent_reset: the parent class' reset handler.
+ *
+ * A model of the v7M NVIC and System Controller
+ */
+typedef struct NVICClass {
+    /*< private >*/
+    ARMGICClass parent_class;
+    /*< public >*/
+    int (*parent_init)(SysBusDevice *dev);
+    void (*parent_reset)(DeviceState *dev);
+} NVICClass;
+
+#define NVIC_CLASS(klass) \
+    OBJECT_CLASS_CHECK(NVICClass, (klass), TYPE_NVIC)
+#define NVIC_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(NVICClass, (obj), TYPE_NVIC)
+#define NVIC(obj) \
+    OBJECT_CHECK(nvic_state, (obj), TYPE_NVIC)
+
 static const uint8_t nvic_id[] = {
     0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1
 };
@@ -429,8 +445,9 @@ static const VMStateDescription vmstate_nvic = {
 
 static void armv7m_nvic_reset(DeviceState *dev)
 {
-    nvic_state *s = FROM_SYSBUSGIC(nvic_state, sysbus_from_qdev(dev));
-    gic_reset(&s->gic.busdev.qdev);
+    nvic_state *s = NVIC(dev);
+    NVICClass *nc = NVIC_GET_CLASS(s);
+    nc->parent_reset(dev);
     /* Common GIC reset resets to disabled; the NVIC doesn't have
      * per-CPU interfaces so mark our non-existent CPU interface
      * as enabled by default.
@@ -443,12 +460,15 @@ static void armv7m_nvic_reset(DeviceState *dev)
 
 static int armv7m_nvic_init(SysBusDevice *dev)
 {
-    nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev);
+    nvic_state *s = NVIC(dev);
+    NVICClass *nc = NVIC_GET_CLASS(s);
 
     /* The NVIC always has only one CPU */
     s->gic.num_cpu = 1;
     /* Tell the common code we're an NVIC */
     s->gic.revision = 0xffffffff;
+    s->gic.num_irq = s->num_irq;
+    nc->parent_init(dev);
     gic_init_irqs_and_distributor(&s->gic, s->num_irq);
     /* The NVIC and system controller register area looks like this:
      *  0..0xff : system control registers, including systick
@@ -489,9 +509,12 @@ static Property armv7m_nvic_properties[] = {
 
 static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
 {
+    NVICClass *nc = NVIC_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
 
+    nc->parent_reset = dc->reset;
+    nc->parent_init = sdc->init;
     sdc->init = armv7m_nvic_init;
     dc->vmsd  = &vmstate_nvic;
     dc->reset = armv7m_nvic_reset;
@@ -499,10 +522,11 @@ static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
 }
 
 static TypeInfo armv7m_nvic_info = {
-    .name          = "armv7m_nvic",
-    .parent        = TYPE_SYS_BUS_DEVICE,
+    .name          = TYPE_NVIC,
+    .parent        = TYPE_ARM_GIC_COMMON,
     .instance_size = sizeof(nvic_state),
     .class_init    = armv7m_nvic_class_init,
+    .class_size    = sizeof(NVICClass),
 };
 
 static void armv7m_nvic_register_types(void)
-- 
1.7.1

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

* [Qemu-devel] [PATCH 12/16] hw/omap.h: Drop broken MEM_VERBOSE tracing
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
                   ` (10 preceding siblings ...)
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 11/16] hw/armv7m_nvic: Make the NVIC a freestanding class Peter Maydell
@ 2012-06-19 13:31 ` Peter Maydell
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 13/16] hw/a9mpcore: Fix compilation failure if physaddrs are 64 bit Peter Maydell
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:31 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Remove the MEM_VERBOSE tracing option from omap.h. This worked by
intercepting cpu_register_io_memory() calls; it has been broken
since cpu_register_io_memory() was removed in favour of the
MemoryRegion API.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/omap.h |   95 -------------------------------------------------------------
 1 files changed, 0 insertions(+), 95 deletions(-)

diff --git a/hw/omap.h b/hw/omap.h
index 2819e5d..3d98941 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -998,7 +998,6 @@ enum {
 #define OMAP_GPIOSW_OUTPUT	0x0002
 
 # define TCMI_VERBOSE			1
-//# define MEM_VERBOSE			1
 
 # ifdef TCMI_VERBOSE
 #  define OMAP_8B_REG(paddr)		\
@@ -1018,98 +1017,4 @@ enum {
 
 # define OMAP_MPUI_REG_MASK		0x000007ff
 
-# ifdef MEM_VERBOSE
-struct io_fn {
-    CPUReadMemoryFunc * const *mem_read;
-    CPUWriteMemoryFunc * const *mem_write;
-    void *opaque;
-    int in;
-};
-
-static uint32_t io_readb(void *opaque, target_phys_addr_t addr)
-{
-    struct io_fn *s = opaque;
-    uint32_t ret;
-
-    s->in ++;
-    ret = s->mem_read[0](s->opaque, addr);
-    s->in --;
-    if (!s->in)
-        fprintf(stderr, "%08x ---> %02x\n", (uint32_t) addr, ret);
-    return ret;
-}
-static uint32_t io_readh(void *opaque, target_phys_addr_t addr)
-{
-    struct io_fn *s = opaque;
-    uint32_t ret;
-
-    s->in ++;
-    ret = s->mem_read[1](s->opaque, addr);
-    s->in --;
-    if (!s->in)
-        fprintf(stderr, "%08x ---> %04x\n", (uint32_t) addr, ret);
-    return ret;
-}
-static uint32_t io_readw(void *opaque, target_phys_addr_t addr)
-{
-    struct io_fn *s = opaque;
-    uint32_t ret;
-
-    s->in ++;
-    ret = s->mem_read[2](s->opaque, addr);
-    s->in --;
-    if (!s->in)
-        fprintf(stderr, "%08x ---> %08x\n", (uint32_t) addr, ret);
-    return ret;
-}
-static void io_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-    struct io_fn *s = opaque;
-
-    if (!s->in)
-        fprintf(stderr, "%08x <--- %02x\n", (uint32_t) addr, value);
-    s->in ++;
-    s->mem_write[0](s->opaque, addr, value);
-    s->in --;
-}
-static void io_writeh(void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-    struct io_fn *s = opaque;
-
-    if (!s->in)
-        fprintf(stderr, "%08x <--- %04x\n", (uint32_t) addr, value);
-    s->in ++;
-    s->mem_write[1](s->opaque, addr, value);
-    s->in --;
-}
-static void io_writew(void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-    struct io_fn *s = opaque;
-
-    if (!s->in)
-        fprintf(stderr, "%08x <--- %08x\n", (uint32_t) addr, value);
-    s->in ++;
-    s->mem_write[2](s->opaque, addr, value);
-    s->in --;
-}
-
-static CPUReadMemoryFunc * const io_readfn[] = { io_readb, io_readh, io_readw, };
-static CPUWriteMemoryFunc * const io_writefn[] = { io_writeb, io_writeh, io_writew, };
-
-inline static int debug_register_io_memory(CPUReadMemoryFunc * const *mem_read,
-                                           CPUWriteMemoryFunc * const *mem_write,
-                                           void *opaque)
-{
-    struct io_fn *s = g_malloc(sizeof(struct io_fn));
-
-    s->mem_read = mem_read;
-    s->mem_write = mem_write;
-    s->opaque = opaque;
-    s->in = 0;
-    return cpu_register_io_memory(io_readfn, io_writefn, s,
-                                  DEVICE_NATIVE_ENDIAN);
-}
-#  define cpu_register_io_memory	debug_register_io_memory
-# endif
-
 #endif /* hw_omap_h */
-- 
1.7.1

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

* [Qemu-devel] [PATCH 13/16] hw/a9mpcore: Fix compilation failure if physaddrs are 64 bit
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
                   ` (11 preceding siblings ...)
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 12/16] hw/omap.h: Drop broken MEM_VERBOSE tracing Peter Maydell
@ 2012-06-19 13:31 ` Peter Maydell
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 14/16] cadence_gem: avoid stack-writing buffer-overrun Peter Maydell
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:31 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Add a cast to a logging printf to avoid a compilation failure
if target_phys_addr_t is a 64 bit type. (This is better than
using TARGET_FMT_plx because we really don't need a full
16 digit hex string to print the offset into a device.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 hw/a9mpcore.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index c2ff74d..ebd5b29 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -75,7 +75,7 @@ static void a9_scu_write(void *opaque, target_phys_addr_t offset,
         break;
     default:
         fprintf(stderr, "Invalid size %u in write to a9 scu register %x\n",
-                size, offset);
+                size, (unsigned)offset);
         return;
     }
 
-- 
1.7.1

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

* [Qemu-devel] [PATCH 14/16] cadence_gem: avoid stack-writing buffer-overrun
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
                   ` (12 preceding siblings ...)
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 13/16] hw/a9mpcore: Fix compilation failure if physaddrs are 64 bit Peter Maydell
@ 2012-06-19 13:31 ` Peter Maydell
  2012-06-20  1:47   ` Peter Crosthwaite
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 15/16] cadence_ttc: changed master clock frequency Peter Maydell
                   ` (2 subsequent siblings)
  16 siblings, 1 reply; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:31 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

From: Jim Meyering <meyering@redhat.com>

Use sizeof(rxbuf)-size (not sizeof(rxbuf-size)) as the number
of bytes to clear.  The latter would always clear 4 or 8
bytes, possibly writing beyond the end of that stack buffer.
Alternatively, depending on the value of the "size" parameter,
it could fail to initialize the end of "rxbuf".
Spotted by coverity.

Signed-off-by: Jim Meyering <meyering@redhat.com>
Reviewed-by: Peter A.G. Crosthwaite <peter.crosthwaite@petalogix.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/cadence_gem.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/cadence_gem.c b/hw/cadence_gem.c
index e2140ae..dbde392 100644
--- a/hw/cadence_gem.c
+++ b/hw/cadence_gem.c
@@ -664,7 +664,7 @@ static ssize_t gem_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
          */
 
         memcpy(rxbuf, buf, size);
-        memset(rxbuf + size, 0, sizeof(rxbuf - size));
+        memset(rxbuf + size, 0, sizeof(rxbuf) - size);
         rxbuf_ptr = rxbuf;
         crc_val = cpu_to_le32(crc32(0, rxbuf, MAX(size, 60)));
         if (size < 60) {
-- 
1.7.1

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

* [Qemu-devel] [PATCH 15/16] cadence_ttc: changed master clock frequency
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
                   ` (13 preceding siblings ...)
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 14/16] cadence_gem: avoid stack-writing buffer-overrun Peter Maydell
@ 2012-06-19 13:31 ` Peter Maydell
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 16/16] arm_boot: Conditionalised DTB command line update Peter Maydell
  2012-06-24 12:26 ` [Qemu-devel] [PULL 00/16] arm-devs queue Blue Swirl
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:31 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

From: Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com>

Change the timer clock frequency to 133MHz which is correct. the old 2.5MHz
value was for the pre-silicon emulation platform.

Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/cadence_ttc.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/cadence_ttc.c b/hw/cadence_ttc.c
index 2b5477b..dd02f86 100644
--- a/hw/cadence_ttc.c
+++ b/hw/cadence_ttc.c
@@ -405,7 +405,7 @@ static int cadence_ttc_init(SysBusDevice *dev)
     int i;
 
     for (i = 0; i < 3; ++i) {
-        cadence_timer_init(2500000, &s->timer[i]);
+        cadence_timer_init(133000000, &s->timer[i]);
         sysbus_init_irq(dev, &s->timer[i].irq);
     }
 
-- 
1.7.1

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

* [Qemu-devel] [PATCH 16/16] arm_boot: Conditionalised DTB command line update
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
                   ` (14 preceding siblings ...)
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 15/16] cadence_ttc: changed master clock frequency Peter Maydell
@ 2012-06-19 13:31 ` Peter Maydell
  2012-06-24 12:26 ` [Qemu-devel] [PULL 00/16] arm-devs queue Blue Swirl
  16 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2012-06-19 13:31 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

From: Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com>

The DTB command line should only be overwritten if the user provides a command
line with -append. Otherwise whatever command line was in the DTB should stay
unchanged.

Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm_boot.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index d0e643b..a1e6ddb 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -242,10 +242,12 @@ static int load_dtb(target_phys_addr_t addr, const struct arm_boot_info *binfo)
         fprintf(stderr, "couldn't set /memory/reg\n");
     }
 
-    rc = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
-                                      binfo->kernel_cmdline);
-    if (rc < 0) {
-        fprintf(stderr, "couldn't set /chosen/bootargs\n");
+    if (binfo->kernel_cmdline && *binfo->kernel_cmdline) {
+        rc = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
+                                          binfo->kernel_cmdline);
+        if (rc < 0) {
+            fprintf(stderr, "couldn't set /chosen/bootargs\n");
+        }
     }
 
     if (binfo->initrd_size) {
-- 
1.7.1

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

* Re: [Qemu-devel] [PATCH 14/16] cadence_gem: avoid stack-writing buffer-overrun
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 14/16] cadence_gem: avoid stack-writing buffer-overrun Peter Maydell
@ 2012-06-20  1:47   ` Peter Crosthwaite
  0 siblings, 0 replies; 19+ messages in thread
From: Peter Crosthwaite @ 2012-06-20  1:47 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Blue Swirl, Anthony Liguori, qemu-devel, Paul Brook

I re-sent this yesterday to trivial.

May end up getting queued for merge twice.

On Tue, Jun 19, 2012 at 11:31 PM, Peter Maydell
<peter.maydell@linaro.org> wrote:
> From: Jim Meyering <meyering@redhat.com>
>
> Use sizeof(rxbuf)-size (not sizeof(rxbuf-size)) as the number
> of bytes to clear.  The latter would always clear 4 or 8
> bytes, possibly writing beyond the end of that stack buffer.
> Alternatively, depending on the value of the "size" parameter,
> it could fail to initialize the end of "rxbuf".
> Spotted by coverity.
>
> Signed-off-by: Jim Meyering <meyering@redhat.com>
> Reviewed-by: Peter A.G. Crosthwaite <peter.crosthwaite@petalogix.com>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/cadence_gem.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/hw/cadence_gem.c b/hw/cadence_gem.c
> index e2140ae..dbde392 100644
> --- a/hw/cadence_gem.c
> +++ b/hw/cadence_gem.c
> @@ -664,7 +664,7 @@ static ssize_t gem_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
>          */
>
>         memcpy(rxbuf, buf, size);
> -        memset(rxbuf + size, 0, sizeof(rxbuf - size));
> +        memset(rxbuf + size, 0, sizeof(rxbuf) - size);
>         rxbuf_ptr = rxbuf;
>         crc_val = cpu_to_le32(crc32(0, rxbuf, MAX(size, 60)));
>         if (size < 60) {
> --
> 1.7.1
>
>

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

* Re: [Qemu-devel] [PULL 00/16] arm-devs queue
  2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
                   ` (15 preceding siblings ...)
  2012-06-19 13:31 ` [Qemu-devel] [PATCH 16/16] arm_boot: Conditionalised DTB command line update Peter Maydell
@ 2012-06-24 12:26 ` Blue Swirl
  16 siblings, 0 replies; 19+ messages in thread
From: Blue Swirl @ 2012-06-24 12:26 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Anthony Liguori, qemu-devel, Paul Brook

On Tue, Jun 19, 2012 at 1:30 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Hi; this is an arm-devs pullreq which mostly has patches which I've
> had queued since before freeze and my holiday. (I had to make a
> trivial fix to one of the GIC patches to account for the list of
> object files moving from Makefile.target to hw/arm/Makefile.objs
> but otherwise an unproblematic rebase to current master.)
> I know there are other arm devs patches on my to-review list but
> this seems a long enough set of patches to be worth sending a
> pullreq for now.
>
> Please pull.

Thanks, pulled.

>
> -- PMM
>
> The following changes since commit 8aca521512a14c439624191bd0a891c52f91b401:
>
>  Merge remote-tracking branch 'afaerber-or/qom-next-2' into staging (2012-06-18 10:35:16 -0500)
>
> are available in the git repository at:
>
>  git://git.linaro.org/people/pmaydell/qemu-arm.git arm-devs.for-upstream
>
> Andreas Färber (1):
>      arm_boot: Fix typos in comment
>
> Evgeny Voevodin (1):
>      ARM: Exynos4210 IRQ: Introduce new IRQ gate functionality.
>
> Jim Meyering (1):
>      cadence_gem: avoid stack-writing buffer-overrun
>
> Peter A. G. Crosthwaite (2):
>      cadence_ttc: changed master clock frequency
>      arm_boot: Conditionalised DTB command line update
>
> Peter Maydell (11):
>      hw/arm_gic: Remove NVIC ifdefs from gic_state struct
>      hw/arm_gic: Remove the special casing of NCPU for the NVIC
>      hw/arm_gic: Move NVIC specific reset to armv7m_nvic_reset
>      hw/armv7m_nvic: Use MemoryRegions for NVIC specific registers
>      hw/arm_gic: Add qdev property for GIC revision
>      hw/arm_gic: Make CPU target registers RAZ/WI on uniprocessor
>      hw/arm_gic.c: Make NVIC interrupt numbering a runtime setting
>      hw/arm_gic: Move CPU interface memory region setup into arm_gic_init
>      hw/armv7m_nvic: Make the NVIC a freestanding class
>      hw/omap.h: Drop broken MEM_VERBOSE tracing
>      hw/a9mpcore: Fix compilation failure if physaddrs are 64 bit
>
>  hw/a15mpcore.c        |    1 +
>  hw/a9mpcore.c         |    2 +-
>  hw/arm-misc.h         |    4 +-
>  hw/arm/Makefile.objs  |    2 +-
>  hw/arm11mpcore.c      |    2 +
>  hw/arm_boot.c         |   10 +-
>  hw/arm_gic.c          |  366 ++++++++-----------------------------------------
>  hw/arm_gic_common.c   |  184 +++++++++++++++++++++++++
>  hw/arm_gic_internal.h |  136 ++++++++++++++++++
>  hw/armv7m_nvic.c      |  138 ++++++++++++++++---
>  hw/cadence_gem.c      |    2 +-
>  hw/cadence_ttc.c      |    2 +-
>  hw/exynos4210.c       |   32 +++--
>  hw/exynos4210.h       |    2 +-
>  hw/exynos4210_gic.c   |   78 +++++-----
>  hw/omap.h             |   95 -------------
>  16 files changed, 569 insertions(+), 487 deletions(-)
>  create mode 100644 hw/arm_gic_common.c
>  create mode 100644 hw/arm_gic_internal.h

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

end of thread, other threads:[~2012-06-24 12:26 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-19 13:30 [Qemu-devel] [PULL 00/16] arm-devs queue Peter Maydell
2012-06-19 13:30 ` [Qemu-devel] [PATCH 01/16] ARM: Exynos4210 IRQ: Introduce new IRQ gate functionality Peter Maydell
2012-06-19 13:30 ` [Qemu-devel] [PATCH 02/16] arm_boot: Fix typos in comment Peter Maydell
2012-06-19 13:31 ` [Qemu-devel] [PATCH 03/16] hw/arm_gic: Remove NVIC ifdefs from gic_state struct Peter Maydell
2012-06-19 13:31 ` [Qemu-devel] [PATCH 04/16] hw/arm_gic: Remove the special casing of NCPU for the NVIC Peter Maydell
2012-06-19 13:31 ` [Qemu-devel] [PATCH 05/16] hw/arm_gic: Move NVIC specific reset to armv7m_nvic_reset Peter Maydell
2012-06-19 13:31 ` [Qemu-devel] [PATCH 06/16] hw/armv7m_nvic: Use MemoryRegions for NVIC specific registers Peter Maydell
2012-06-19 13:31 ` [Qemu-devel] [PATCH 07/16] hw/arm_gic: Add qdev property for GIC revision Peter Maydell
2012-06-19 13:31 ` [Qemu-devel] [PATCH 08/16] hw/arm_gic: Make CPU target registers RAZ/WI on uniprocessor Peter Maydell
2012-06-19 13:31 ` [Qemu-devel] [PATCH 09/16] hw/arm_gic.c: Make NVIC interrupt numbering a runtime setting Peter Maydell
2012-06-19 13:31 ` [Qemu-devel] [PATCH 10/16] hw/arm_gic: Move CPU interface memory region setup into arm_gic_init Peter Maydell
2012-06-19 13:31 ` [Qemu-devel] [PATCH 11/16] hw/armv7m_nvic: Make the NVIC a freestanding class Peter Maydell
2012-06-19 13:31 ` [Qemu-devel] [PATCH 12/16] hw/omap.h: Drop broken MEM_VERBOSE tracing Peter Maydell
2012-06-19 13:31 ` [Qemu-devel] [PATCH 13/16] hw/a9mpcore: Fix compilation failure if physaddrs are 64 bit Peter Maydell
2012-06-19 13:31 ` [Qemu-devel] [PATCH 14/16] cadence_gem: avoid stack-writing buffer-overrun Peter Maydell
2012-06-20  1:47   ` Peter Crosthwaite
2012-06-19 13:31 ` [Qemu-devel] [PATCH 15/16] cadence_ttc: changed master clock frequency Peter Maydell
2012-06-19 13:31 ` [Qemu-devel] [PATCH 16/16] arm_boot: Conditionalised DTB command line update Peter Maydell
2012-06-24 12:26 ` [Qemu-devel] [PULL 00/16] arm-devs queue Blue Swirl

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.