*/
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "qemu/error-report.h"
+#include "qemu/module.h"
#include "hw/sysbus.h"
#include "target/riscv/cpu.h"
+#include "hw/qdev-properties.h"
#include "hw/riscv/sifive_clint.h"
#include "qemu/timer.h"
error_report("clint: invalid timecmp hartid: %zu", hartid);
} else if ((addr & 0x7) == 0) {
/* timecmp_lo */
- uint64_t timecmp = env->timecmp;
+ uint64_t timecmp_hi = env->timecmp >> 32;
sifive_clint_write_timecmp(RISCV_CPU(cpu),
- timecmp << 32 | (value & 0xFFFFFFFF));
+ timecmp_hi << 32 | (value & 0xFFFFFFFF));
return;
} else if ((addr & 0x7) == 4) {
/* timecmp_hi */
- uint64_t timecmp = env->timecmp;
+ uint64_t timecmp_lo = env->timecmp;
sifive_clint_write_timecmp(RISCV_CPU(cpu),
- value << 32 | (timecmp & 0xFFFFFFFF));
+ value << 32 | (timecmp_lo & 0xFFFFFFFF));
} else {
error_report("clint: invalid timecmp write: %08x", (uint32_t)addr);
}
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4,
- .max_access_size = 4
+ .max_access_size = 8
}
};
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = sifive_clint_realize;
- dc->props = sifive_clint_properties;
+ device_class_set_props(dc, sifive_clint_properties);
}
static const TypeInfo sifive_clint_info = {
* Create CLINT device.
*/
DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, uint32_t num_harts,
- uint32_t sip_base, uint32_t timecmp_base, uint32_t time_base)
+ uint32_t sip_base, uint32_t timecmp_base, uint32_t time_base,
+ bool provide_rdtime)
{
int i;
for (i = 0; i < num_harts; i++) {
if (!env) {
continue;
}
+ if (provide_rdtime) {
+ riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc);
+ }
env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
&sifive_clint_timer_cb, cpu);
env->timecmp = 0;
}
- DeviceState *dev = qdev_create(NULL, TYPE_SIFIVE_CLINT);
+ DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT);
qdev_prop_set_uint32(dev, "num-harts", num_harts);
qdev_prop_set_uint32(dev, "sip-base", sip_base);
qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
qdev_prop_set_uint32(dev, "time-base", time_base);
qdev_prop_set_uint32(dev, "aperture-size", size);
- qdev_init_nofail(dev);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
return dev;
}