qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH arm-devs v2 2/2] cpu/a9mpcore: Add Global Timer


From: peter . crosthwaite
Subject: [Qemu-devel] [PATCH arm-devs v2 2/2] cpu/a9mpcore: Add Global Timer
Date: Mon, 15 Jul 2013 15:19:48 +1000

From: François LEGAL <address@hidden>

Add the global timer to A9 MPCore.

Signed-off-by: François LEGAL <address@hidden>
[PC Changes:
 * new commit message
 * split off original version as a separate patch
]
Signed-off-by: Peter Crosthwaite <address@hidden>
---
This will likely conflict with Andreas' MPCore work.
Changed from v1:
Set authorship to Francois and added SOB.

 hw/cpu/a9mpcore.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
index 6c00a59..56d101e 100644
--- a/hw/cpu/a9mpcore.c
+++ b/hw/cpu/a9mpcore.c
@@ -15,6 +15,7 @@ typedef struct A9MPPrivState {
     uint32_t num_cpu;
     MemoryRegion container;
     DeviceState *mptimer;
+    DeviceState *mpgtimer;
     DeviceState *wdt;
     DeviceState *gic;
     DeviceState *scu;
@@ -31,6 +32,7 @@ static int a9mp_priv_init(SysBusDevice *dev)
 {
     A9MPPrivState *s = FROM_SYSBUS(A9MPPrivState, dev);
     SysBusDevice *timerbusdev, *wdtbusdev, *gicbusdev, *scubusdev;
+    SysBusDevice *gtimerbusdev;
     int i;
 
     s->gic = qdev_create(NULL, "arm_gic");
@@ -50,6 +52,11 @@ static int a9mp_priv_init(SysBusDevice *dev)
     qdev_init_nofail(s->scu);
     scubusdev = SYS_BUS_DEVICE(s->scu);
 
+    s->mpgtimer = qdev_create(NULL, "a9_globaltimer");
+    qdev_prop_set_uint32(s->mpgtimer, "num-cpu", s->num_cpu);
+    qdev_init_nofail(s->mpgtimer);
+    gtimerbusdev = SYS_BUS_DEVICE(s->mpgtimer);
+
     s->mptimer = qdev_create(NULL, "arm_mptimer");
     qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu);
     qdev_init_nofail(s->mptimer);
@@ -68,8 +75,6 @@ static int a9mp_priv_init(SysBusDevice *dev)
      *  0x0600-0x06ff -- private timers and watchdogs
      *  0x0700-0x0fff -- nothing
      *  0x1000-0x1fff -- GIC Distributor
-     *
-     * We should implement the global timer but don't currently do so.
      */
     memory_region_init(&s->container, OBJECT(s), "a9mp-priv-container", 
0x2000);
     memory_region_add_subregion(&s->container, 0,
@@ -80,6 +85,8 @@ static int a9mp_priv_init(SysBusDevice *dev)
     /* Note that the A9 exposes only the "timer/watchdog for this core"
      * memory region, not the "timer/watchdog for core X" ones 11MPcore has.
      */
+    memory_region_add_subregion(&s->container, 0x200,
+                                sysbus_mmio_get_region(gtimerbusdev, 0));
     memory_region_add_subregion(&s->container, 0x600,
                                 sysbus_mmio_get_region(timerbusdev, 0));
     memory_region_add_subregion(&s->container, 0x620,
@@ -90,10 +97,13 @@ static int a9mp_priv_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, &s->container);
 
     /* Wire up the interrupt from each watchdog and timer.
-     * For each core the timer is PPI 29 and the watchdog PPI 30.
+     * For each core the global timer is PPI 27, the private
+     * timer is PPI 29 and the watchdog PPI 30.
      */
     for (i = 0; i < s->num_cpu; i++) {
         int ppibase = (s->num_irq - 32) + i * 32;
+        sysbus_connect_irq(gtimerbusdev, i,
+                           qdev_get_gpio_in(s->gic, ppibase + 27));
         sysbus_connect_irq(timerbusdev, i,
                            qdev_get_gpio_in(s->gic, ppibase + 29));
         sysbus_connect_irq(wdtbusdev, i,
-- 
1.8.3.rc1.44.gb387c77.dirty




reply via email to

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