* Copyright (c) 2006 Openedhand Ltd.
* Copyright (c) 2006 Thorsten Zitterell
*
- * This code is licenced under the GPL.
+ * This code is licensed under the GPL.
*/
#include "hw.h"
struct PXA2xxTimerInfo {
SysBusDevice busdev;
+ MemoryRegion iomem;
uint32_t flags;
int32_t clock;
qemu_mod_timer(s->tm4[n].tm.qtimer, new_qemu);
}
-static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset)
+static uint64_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset,
+ unsigned size)
{
PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
int tm = 0;
goto badreg;
return s->tm4[tm].tm.value;
case OSCR:
- return s->clock + muldiv64(qemu_get_clock(vm_clock) -
+ return s->clock + muldiv64(qemu_get_clock_ns(vm_clock) -
s->lastload, s->freq, get_ticks_per_sec());
case OSCR11: tm ++;
case OSCR10: tm ++;
if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) {
if (s->tm4[tm - 1].freq)
s->snapshot = s->tm4[tm - 1].clock + muldiv64(
- qemu_get_clock(vm_clock) -
+ qemu_get_clock_ns(vm_clock) -
s->tm4[tm - 1].lastload,
s->tm4[tm - 1].freq, get_ticks_per_sec());
else
if (!s->tm4[tm].freq)
return s->tm4[tm].clock;
- return s->tm4[tm].clock + muldiv64(qemu_get_clock(vm_clock) -
+ return s->tm4[tm].clock + muldiv64(qemu_get_clock_ns(vm_clock) -
s->tm4[tm].lastload, s->tm4[tm].freq, get_ticks_per_sec());
case OIER:
return s->irq_enabled;
}
static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
- uint32_t value)
+ uint64_t value, unsigned size)
{
int i, tm = 0;
PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
case OSMR1: tm ++;
case OSMR0:
s->timer[tm].value = value;
- pxa2xx_timer_update(s, qemu_get_clock(vm_clock));
+ pxa2xx_timer_update(s, qemu_get_clock_ns(vm_clock));
break;
case OSMR11: tm ++;
case OSMR10: tm ++;
if (!pxa2xx_timer_has_tm4(s))
goto badreg;
s->tm4[tm].tm.value = value;
- pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
+ pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
break;
case OSCR:
s->oldclock = s->clock;
- s->lastload = qemu_get_clock(vm_clock);
+ s->lastload = qemu_get_clock_ns(vm_clock);
s->clock = value;
pxa2xx_timer_update(s, s->lastload);
break;
if (!pxa2xx_timer_has_tm4(s))
goto badreg;
s->tm4[tm].oldclock = s->tm4[tm].clock;
- s->tm4[tm].lastload = qemu_get_clock(vm_clock);
+ s->tm4[tm].lastload = qemu_get_clock_ns(vm_clock);
s->tm4[tm].clock = value;
pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm);
break;
s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7];
else {
s->tm4[tm].freq = 0;
- pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
+ pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
}
break;
case OMCR11: tm ++;
pxa2xx_timer4_freq[(value & (1 << 8)) ? 0 : (value & 7)];
else {
s->tm4[tm].freq = 0;
- pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
+ pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
}
break;
default:
}
}
-static CPUReadMemoryFunc * const pxa2xx_timer_readfn[] = {
- pxa2xx_timer_read,
- pxa2xx_timer_read,
- pxa2xx_timer_read,
-};
-
-static CPUWriteMemoryFunc * const pxa2xx_timer_writefn[] = {
- pxa2xx_timer_write,
- pxa2xx_timer_write,
- pxa2xx_timer_write,
+static const MemoryRegionOps pxa2xx_timer_ops = {
+ .read = pxa2xx_timer_read,
+ .write = pxa2xx_timer_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void pxa2xx_timer_tick(void *opaque)
if (t->control & (1 << 3))
t->clock = 0;
if (t->control & (1 << 6))
- pxa2xx_timer_update4(i, qemu_get_clock(vm_clock), t->tm.num - 4);
+ pxa2xx_timer_update4(i, qemu_get_clock_ns(vm_clock), t->tm.num - 4);
if (i->events & 0xff0)
qemu_irq_raise(i->irq4);
}
int64_t now;
int i;
- now = qemu_get_clock(vm_clock);
+ now = qemu_get_clock_ns(vm_clock);
pxa2xx_timer_update(s, now);
if (pxa2xx_timer_has_tm4(s))
static int pxa2xx_timer_init(SysBusDevice *dev)
{
int i;
- int iomemtype;
PXA2xxTimerInfo *s;
s = FROM_SYSBUS(PXA2xxTimerInfo, dev);
s->irq_enabled = 0;
s->oldclock = 0;
s->clock = 0;
- s->lastload = qemu_get_clock(vm_clock);
+ s->lastload = qemu_get_clock_ns(vm_clock);
s->reset3 = 0;
for (i = 0; i < 4; i ++) {
sysbus_init_irq(dev, &s->timer[i].irq);
s->timer[i].info = s;
s->timer[i].num = i;
- s->timer[i].qtimer = qemu_new_timer(vm_clock,
+ s->timer[i].qtimer = qemu_new_timer_ns(vm_clock,
pxa2xx_timer_tick, &s->timer[i]);
}
if (s->flags & (1 << PXA2XX_TIMER_HAVE_TM4)) {
s->tm4[i].tm.num = i + 4;
s->tm4[i].freq = 0;
s->tm4[i].control = 0x0;
- s->tm4[i].tm.qtimer = qemu_new_timer(vm_clock,
+ s->tm4[i].tm.qtimer = qemu_new_timer_ns(vm_clock,
pxa2xx_timer_tick4, &s->tm4[i]);
}
}
- iomemtype = cpu_register_io_memory(pxa2xx_timer_readfn,
- pxa2xx_timer_writefn, s, DEVICE_NATIVE_ENDIAN);
- sysbus_init_mmio(dev, 0x00001000, iomemtype);
+ memory_region_init_io(&s->iomem, &pxa2xx_timer_ops, s,
+ "pxa2xx-timer", 0x00001000);
+ sysbus_init_mmio(dev, &s->iomem);
return 0;
}
}
};
-static SysBusDeviceInfo pxa25x_timer_dev_info = {
- .init = pxa2xx_timer_init,
- .qdev.name = "pxa25x-timer",
- .qdev.desc = "PXA25x timer",
- .qdev.size = sizeof(PXA2xxTimerInfo),
- .qdev.vmsd = &vmstate_pxa2xx_timer_regs,
- .qdev.props = (Property[]) {
- DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA25X_FREQ),
- DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
- PXA2XX_TIMER_HAVE_TM4, false),
- DEFINE_PROP_END_OF_LIST(),
- },
+static Property pxa25x_timer_dev_properties[] = {
+ DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA25X_FREQ),
+ DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
+ PXA2XX_TIMER_HAVE_TM4, false),
+ DEFINE_PROP_END_OF_LIST(),
};
-static SysBusDeviceInfo pxa27x_timer_dev_info = {
- .init = pxa2xx_timer_init,
- .qdev.name = "pxa27x-timer",
- .qdev.desc = "PXA27x timer",
- .qdev.size = sizeof(PXA2xxTimerInfo),
- .qdev.vmsd = &vmstate_pxa2xx_timer_regs,
- .qdev.props = (Property[]) {
- DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA27X_FREQ),
- DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
- PXA2XX_TIMER_HAVE_TM4, true),
- DEFINE_PROP_END_OF_LIST(),
- },
+static void pxa25x_timer_dev_class_init(ObjectClass *klass, void *data)
+{
+ SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+ k->init = pxa2xx_timer_init;
+}
+
+static DeviceInfo pxa25x_timer_dev_info = {
+ .name = "pxa25x-timer",
+ .desc = "PXA25x timer",
+ .size = sizeof(PXA2xxTimerInfo),
+ .vmsd = &vmstate_pxa2xx_timer_regs,
+ .props = pxa25x_timer_dev_properties,
+ .class_init = pxa25x_timer_dev_class_init,
+};
+
+static Property pxa27x_timer_dev_properties[] = {
+ DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA27X_FREQ),
+ DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
+ PXA2XX_TIMER_HAVE_TM4, true),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pxa27x_timer_dev_class_init(ObjectClass *klass, void *data)
+{
+ SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+ k->init = pxa2xx_timer_init;
+}
+
+static DeviceInfo pxa27x_timer_dev_info = {
+ .name = "pxa27x-timer",
+ .desc = "PXA27x timer",
+ .size = sizeof(PXA2xxTimerInfo),
+ .vmsd = &vmstate_pxa2xx_timer_regs,
+ .props = pxa27x_timer_dev_properties,
+ .class_init = pxa27x_timer_dev_class_init,
};
static void pxa2xx_timer_register(void)