static uint64_t timerblock_read(void *opaque, target_phys_addr_t addr, unsigned size) { timerblock *tb = (timerblock *)opaque; int64_t val; addr &= 0x1f; switch (addr) { case 0: /* Load */ return tb->load; case 4: /* Counter. */ if (((tb->control & 1) == 0) || (tb->count == 0)) { return 0; } /* Slow and ugly, but hopefully won't happen too often. */ val = tb->tick - qemu_get_clock_ns(vm_clock); val /= timerblock_scale(tb); if (val < 0) { val = 0; } return val; case 8: /* Control. */ return tb->control; case 12: /* Interrupt status. */ return tb->status; default: return 0; } }
static uint64_t timerblock_read(void *opaque, hwaddr addr, unsigned size) { TimerBlock *tb = (TimerBlock *)opaque; int64_t val; switch (addr) { case 0: /* Load */ return tb->load; case 4: /* Counter. */ if (((tb->control & 1) == 0) || (tb->count == 0)) { return 0; } /* Slow and ugly, but hopefully won't happen too often. */ val = tb->tick - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); val /= timerblock_scale(tb); if (val < 0) { val = 0; } return val; case 8: /* Control. */ return tb->control; case 12: /* Interrupt status. */ return tb->status; default: return 0; } }
static void timerblock_reload(TimerBlock *tb, int restart) { if (tb->count == 0) { return; } if (restart) { tb->tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); } tb->tick += (int64_t)tb->count * timerblock_scale(tb); timer_mod(tb->timer, tb->tick); }
static void timerblock_reload(timerblock *tb, int restart) { if (tb->count == 0) { return; } if (restart) { tb->tick = qemu_get_clock_ns(vm_clock); } tb->tick += (int64_t)tb->count * timerblock_scale(tb); qemu_mod_timer(tb->timer, tb->tick); }