*/
#include "sysbus.h"
-#include "sysemu.h"
#include "qemu-timer.h"
#define D(x)
struct timerblock
{
SysBusDevice busdev;
+ MemoryRegion mmio;
qemu_irq irq;
- unsigned int nr_timers;
+ uint32_t nr_timers;
+ uint32_t freq_hz;
struct xlx_timer *timers;
};
qemu_set_irq(t->irq, !!irq);
}
-static uint32_t timer_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t
+timer_read(void *opaque, target_phys_addr_t addr, unsigned int size)
{
struct timerblock *t = opaque;
struct xlx_timer *xt;
}
static void
-timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+timer_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val64, unsigned int size)
{
struct timerblock *t = opaque;
struct xlx_timer *xt;
unsigned int timer;
+ uint32_t value = val64;
addr >>= 2;
timer = timer_from_addr(addr);
timer_update_irq(t);
}
-static CPUReadMemoryFunc *timer_read[] = {
- NULL, NULL,
- &timer_readl,
-};
-
-static CPUWriteMemoryFunc *timer_write[] = {
- NULL, NULL,
- &timer_writel,
+static const MemoryRegionOps timer_ops = {
+ .read = timer_read,
+ .write = timer_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4
+ }
};
static void timer_hit(void *opaque)
timer_update_irq(t);
}
-static void xilinx_timer_init(SysBusDevice *dev)
+static int xilinx_timer_init(SysBusDevice *dev)
{
struct timerblock *t = FROM_SYSBUS(typeof (*t), dev);
unsigned int i;
- int timer_regs, freq_hz;
/* All timers share a single irq line. */
sysbus_init_irq(dev, &t->irq);
/* Init all the ptimers. */
- freq_hz = qdev_get_prop_int(&dev->qdev, "frequency", 2);
- t->nr_timers = qdev_get_prop_int(&dev->qdev, "nr-timers", 2);
- t->timers = qemu_mallocz(sizeof t->timers[0] * t->nr_timers);
+ t->timers = g_malloc0(sizeof t->timers[0] * t->nr_timers);
for (i = 0; i < t->nr_timers; i++) {
struct xlx_timer *xt = &t->timers[i];
xt->nr = i;
xt->bh = qemu_bh_new(timer_hit, xt);
xt->ptimer = ptimer_init(xt->bh);
- ptimer_set_freq(xt->ptimer, freq_hz);
+ ptimer_set_freq(xt->ptimer, t->freq_hz);
}
- timer_regs = cpu_register_io_memory(timer_read, timer_write, t);
- sysbus_init_mmio(dev, R_MAX * 4 * t->nr_timers, timer_regs);
+ memory_region_init_io(&t->mmio, &timer_ops, t, "xilinx-timer",
+ R_MAX * 4 * t->nr_timers);
+ sysbus_init_mmio_region(dev, &t->mmio);
+ return 0;
}
+static SysBusDeviceInfo xilinx_timer_info = {
+ .init = xilinx_timer_init,
+ .qdev.name = "xilinx,timer",
+ .qdev.size = sizeof(struct timerblock),
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_UINT32("frequency", struct timerblock, freq_hz, 0),
+ DEFINE_PROP_UINT32("nr-timers", struct timerblock, nr_timers, 0),
+ DEFINE_PROP_END_OF_LIST(),
+ }
+};
+
static void xilinx_timer_register(void)
{
- sysbus_register_dev("xilinx,timer", sizeof (struct timerblock),
- xilinx_timer_init);
+ sysbus_register_withprop(&xilinx_timer_info);
}
device_init(xilinx_timer_register)