mirror of
https://github.com/qemu/qemu.git
synced 2024-11-25 20:03:37 +08:00
cpu/a9mpcore: Add Global Timer
Add the global timer to A9 MPCore. Signed-off-by: François LEGAL <devel@thom.fr.eu.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: ff92f35f438ac671b57d99d823723dd3e62d2c49.1385969450.git.peter.crosthwaite@xilinx.com [PC Changes: * new commit message * split off original version as a separate patch * Rebased against new mpcore implementation (with struct embedding) ] Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
c21c3b53e1
commit
57e72f2a19
@ -30,6 +30,9 @@ static void a9mp_priv_initfn(Object *obj)
|
||||
object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC);
|
||||
qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
|
||||
|
||||
object_initialize(&s->gtimer, sizeof(s->gtimer), TYPE_A9_GTIMER);
|
||||
qdev_set_parent_bus(DEVICE(&s->gtimer), sysbus_get_default());
|
||||
|
||||
object_initialize(&s->mptimer, sizeof(s->mptimer), TYPE_ARM_MPTIMER);
|
||||
qdev_set_parent_bus(DEVICE(&s->mptimer), sysbus_get_default());
|
||||
|
||||
@ -41,8 +44,9 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
A9MPPrivState *s = A9MPCORE_PRIV(dev);
|
||||
DeviceState *scudev, *gicdev, *mptimerdev, *wdtdev;
|
||||
SysBusDevice *scubusdev, *gicbusdev, *mptimerbusdev, *wdtbusdev;
|
||||
DeviceState *scudev, *gicdev, *gtimerdev, *mptimerdev, *wdtdev;
|
||||
SysBusDevice *scubusdev, *gicbusdev, *gtimerbusdev, *mptimerbusdev,
|
||||
*wdtbusdev;
|
||||
Error *err = NULL;
|
||||
int i;
|
||||
|
||||
@ -71,6 +75,15 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
|
||||
/* Pass through inbound GPIO lines to the GIC */
|
||||
qdev_init_gpio_in(dev, a9mp_priv_set_irq, s->num_irq - 32);
|
||||
|
||||
gtimerdev = DEVICE(&s->gtimer);
|
||||
qdev_prop_set_uint32(gtimerdev, "num-cpu", s->num_cpu);
|
||||
object_property_set_bool(OBJECT(&s->gtimer), true, "realized", &err);
|
||||
if (err != NULL) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
gtimerbusdev = SYS_BUS_DEVICE(&s->gtimer);
|
||||
|
||||
mptimerdev = DEVICE(&s->mptimer);
|
||||
qdev_prop_set_uint32(mptimerdev, "num-cpu", s->num_cpu);
|
||||
object_property_set_bool(OBJECT(&s->mptimer), true, "realized", &err);
|
||||
@ -97,14 +110,14 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
|
||||
* 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_add_subregion(&s->container, 0,
|
||||
sysbus_mmio_get_region(scubusdev, 0));
|
||||
/* GIC CPU interface */
|
||||
memory_region_add_subregion(&s->container, 0x100,
|
||||
sysbus_mmio_get_region(gicbusdev, 1));
|
||||
memory_region_add_subregion(&s->container, 0x200,
|
||||
sysbus_mmio_get_region(gtimerbusdev, 0));
|
||||
/* Note that the A9 exposes only the "timer/watchdog for this core"
|
||||
* memory region, not the "timer/watchdog for core X" ones 11MPcore has.
|
||||
*/
|
||||
@ -116,10 +129,13 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
|
||||
sysbus_mmio_get_region(gicbusdev, 0));
|
||||
|
||||
/* 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(gicdev, ppibase + 27));
|
||||
sysbus_connect_irq(mptimerbusdev, i,
|
||||
qdev_get_gpio_in(gicdev, ppibase + 29));
|
||||
sysbus_connect_irq(wdtbusdev, i,
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "hw/intc/arm_gic.h"
|
||||
#include "hw/misc/a9scu.h"
|
||||
#include "hw/timer/arm_mptimer.h"
|
||||
#include "hw/timer/a9gtimer.h"
|
||||
|
||||
#define TYPE_A9MPCORE_PRIV "a9mpcore_priv"
|
||||
#define A9MPCORE_PRIV(obj) \
|
||||
@ -30,6 +31,7 @@ typedef struct A9MPPrivState {
|
||||
|
||||
A9SCUState scu;
|
||||
GICState gic;
|
||||
A9GTimerState gtimer;
|
||||
ARMMPTimerState mptimer;
|
||||
ARMMPTimerState wdt;
|
||||
} A9MPPrivState;
|
||||
|
Loading…
Reference in New Issue
Block a user