static uint64_t timer_read(void *opaque, hwaddr addr, unsigned int size) { struct etrax_timer *t = opaque; uint32_t r = 0; switch (addr) { case R_TMR0_DATA: r = ptimer_get_count(t->ptimer_t0); break; case R_TMR1_DATA: r = ptimer_get_count(t->ptimer_t1); break; case R_TIME: r = qemu_get_clock_ns(vm_clock) / 10; break; case RW_INTR_MASK: r = t->rw_intr_mask; break; case R_MASKED_INTR: r = t->r_intr & t->rw_intr_mask; break; default: D(printf ("%s %x\n", __func__, addr)); break; } return r; }
static uint64_t timer_read(void *opaque, hwaddr addr, unsigned int size) { struct timerblock *t = opaque; struct xlx_timer *xt; uint32_t r = 0; unsigned int timer; addr >>= 2; timer = timer_from_addr(addr); xt = &t->timers[timer]; /* Further decoding to address a specific timers reg. */ addr &= 0x3; switch (addr) { case R_TCR: r = ptimer_get_count(xt->ptimer); if (!(xt->regs[R_TCSR] & TCSR_UDT)) r = ~r; D(qemu_log("xlx_timer t=%d read counter=%x udt=%d\n", timer, r, xt->regs[R_TCSR] & TCSR_UDT)); break; default: if (addr < ARRAY_SIZE(xt->regs)) r = xt->regs[addr]; break; } D(fprintf(stderr, "%s timer=%d %x=%x\n", __func__, timer, addr * 4, r)); return r; }
static uint64_t grlib_gptimer_read(void *opaque, hwaddr addr, unsigned size) { GPTimerUnit *unit = opaque; hwaddr timer_addr; int id; uint32_t value = 0; addr &= 0xff; /* Unit registers */ switch (addr) { case SCALER_OFFSET: trace_grlib_gptimer_readl(-1, addr, unit->scaler); return unit->scaler; case SCALER_RELOAD_OFFSET: trace_grlib_gptimer_readl(-1, addr, unit->reload); return unit->reload; case CONFIG_OFFSET: trace_grlib_gptimer_readl(-1, addr, unit->config); return unit->config; default: break; } timer_addr = (addr % TIMER_BASE); id = (addr - TIMER_BASE) / TIMER_BASE; if (id >= 0 && id < unit->nr_timers) { /* GPTimer registers */ switch (timer_addr) { case COUNTER_OFFSET: value = ptimer_get_count(unit->timers[id].ptimer); trace_grlib_gptimer_readl(id, addr, value); return value; case COUNTER_RELOAD_OFFSET: value = unit->timers[id].reload; trace_grlib_gptimer_readl(id, addr, value); return value; case CONFIG_OFFSET: trace_grlib_gptimer_readl(id, addr, unit->timers[id].config); return unit->timers[id].config; default: break; } } trace_grlib_gptimer_readl(-1, addr, 0); return 0; }
static uint32_t grlib_gptimer_readl(void *opaque, target_phys_addr_t addr) { GPTimerUnit *unit = opaque; target_phys_addr_t timer_addr; int id; uint32_t value = 0; addr &= 0xff; /* Unit registers */ switch (addr) { case SCALER_OFFSET: trace_grlib_gptimer_readl(-1, "scaler:", unit->scaler); return unit->scaler; case SCALER_RELOAD_OFFSET: trace_grlib_gptimer_readl(-1, "reload:", unit->reload); return unit->reload; case CONFIG_OFFSET: trace_grlib_gptimer_readl(-1, "config:", unit->config); return unit->config; default: break; } timer_addr = (addr % TIMER_BASE); id = (addr - TIMER_BASE) / TIMER_BASE; if (id >= 0 && id < unit->nr_timers) { /* GPTimer registers */ switch (timer_addr) { case COUNTER_OFFSET: value = ptimer_get_count(unit->timers[id].ptimer); trace_grlib_gptimer_readl(id, "counter value:", value); return value; case COUNTER_RELOAD_OFFSET: value = unit->timers[id].reload; trace_grlib_gptimer_readl(id, "reload value:", value); return value; case CONFIG_OFFSET: trace_grlib_gptimer_readl(id, "scaler value:", unit->timers[id].config); return unit->timers[id].config; default: break; } } trace_grlib_gptimer_unknown_register("read", addr); return 0; }
static uint64_t sysctl_read(void *opaque, hwaddr addr, unsigned size) { MilkymistSysctlState *s = opaque; uint32_t r = 0; addr >>= 2; switch (addr) { case R_TIMER0_COUNTER: r = (uint32_t)ptimer_get_count(s->ptimer0); /* milkymist timer counts up */ r = s->regs[R_TIMER0_COMPARE] - r; break; case R_TIMER1_COUNTER: r = (uint32_t)ptimer_get_count(s->ptimer1); /* milkymist timer counts up */ r = s->regs[R_TIMER1_COMPARE] - r; break; case R_GPIO_IN: case R_GPIO_OUT: case R_GPIO_INTEN: case R_TIMER0_CONTROL: case R_TIMER0_COMPARE: case R_TIMER1_CONTROL: case R_TIMER1_COMPARE: case R_ICAP: case R_DBG_SCRATCHPAD: case R_DBG_WRITE_LOCK: case R_CLK_FREQUENCY: case R_CAPABILITIES: case R_SYSTEM_ID: r = s->regs[addr]; break; default: error_report("milkymist_sysctl: read access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } trace_milkymist_sysctl_memory_read(addr << 2, r); return r; }
static uint64_t timer_read(void *opaque, hwaddr offset, unsigned int size) { MSSTimerState *t = opaque; hwaddr addr; struct Msf2Timer *st; uint32_t ret = 0; int timer = 0; int isr; int ier; addr = offset >> 2; /* * Two independent timers has same base address. * Based on address passed figure out which timer is being used. */ if ((addr >= R_TIM1_MAX) && (addr < NUM_TIMERS * R_TIM1_MAX)) { timer = 1; addr -= R_TIM1_MAX; } st = &t->timers[timer]; switch (addr) { case R_TIM_VAL: ret = ptimer_get_count(st->ptimer); break; case R_TIM_MIS: isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK); ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR); ret = ier & isr; break; default: if (addr < R_TIM1_MAX) { ret = st->regs[addr]; } else { qemu_log_mask(LOG_GUEST_ERROR, TYPE_MSS_TIMER": 64-bit mode not supported\n"); return ret; } break; } DB_PRINT("timer=%d 0x%" HWADDR_PRIx "=0x%" PRIx32, timer, offset, ret); return ret; }
// Update count, set irq, update expire_time // Convert from ptimer countdown units static void slavio_timer_get_out(CPUTimerState *t) { uint64_t count, limit; if (t->limit == 0) { /* free-run system or processor counter */ limit = TIMER_MAX_COUNT32; } else { limit = t->limit; } count = limit - PERIODS_TO_LIMIT(ptimer_get_count(t->timer)); trace_slavio_timer_get_out(t->limit, t->counthigh, t->count); t->count = count & TIMER_COUNT_MASK32; t->counthigh = count >> 32; }
static uint64_t pit_ctr_pr(RegisterInfo *reg, uint64_t val) { XilinxPIT *s = XILINX_IO_MODULE_PIT(reg->opaque); uint32_t r; if (!s->cfg.use) { qemu_log_mask(LOG_GUEST_ERROR, "%s: Disabled\n", s->prefix); return 0xdeadbeef; } if (s->ps_enable) { r = s->ps_counter; } else { r = ptimer_get_count(s->ptimer); } return r; }
static uint64_t a10_pit_read(void *opaque, hwaddr offset, unsigned size) { AwA10PITState *s = AW_A10_PIT(opaque); uint8_t index; switch (offset) { case AW_A10_PIT_TIMER_IRQ_EN: return s->irq_enable; case AW_A10_PIT_TIMER_IRQ_ST: return s->irq_status; case AW_A10_PIT_TIMER_BASE ... AW_A10_PIT_TIMER_BASE_END: index = offset & 0xf0; index >>= 4; index -= 1; switch (offset & 0x0f) { case AW_A10_PIT_TIMER_CONTROL: return s->control[index]; case AW_A10_PIT_TIMER_INTERVAL: return s->interval[index]; case AW_A10_PIT_TIMER_COUNT: s->count[index] = ptimer_get_count(s->timer[index]); return s->count[index]; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%x\n", __func__, (int)offset); break; } case AW_A10_PIT_WDOG_CONTROL: break; case AW_A10_PIT_WDOG_MODE: break; case AW_A10_PIT_COUNT_LO: return s->count_lo; case AW_A10_PIT_COUNT_HI: return s->count_hi; case AW_A10_PIT_COUNT_CTL: return s->count_ctl; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%x\n", __func__, (int)offset); break; } return 0; }
static uint32_t sh_timer_read(void *opaque, target_phys_addr_t offset) { sh_timer_state *s = (sh_timer_state *)opaque; switch (offset >> 2) { case OFFSET_TCOR: return s->tcor; case OFFSET_TCNT: return ptimer_get_count(s->timer); case OFFSET_TCR: return s->tcr | (s->int_level ? TIMER_TCR_UNF : 0); case OFFSET_TCPR: if (s->feat & TIMER_FEAT_CAPT) return s->tcpr; default: hw_error("sh_timer_read: Bad offset %x\n", (int)offset); return 0; } }
// Update count, set irq, update expire_time // Convert from ptimer countdown units static void slavio_timer_get_out(SLAVIO_TIMERState *s) { uint64_t count, limit; if (s->limit == 0) /* free-run processor or system counter */ limit = TIMER_MAX_COUNT32; else limit = s->limit; if (s->timer) count = limit - PERIODS_TO_LIMIT(ptimer_get_count(s->timer)); else count = 0; DPRINTF("get_out: limit %" PRIx64 " count %x%08x\n", s->limit, s->counthigh, s->count); s->count = count & TIMER_COUNT_MASK32; s->counthigh = count >> 32; }
static uint64_t puv3_ost_read(void *opaque, target_phys_addr_t offset, unsigned size) { PUV3OSTState *s = opaque; uint32_t ret = 0; switch (offset) { case 0x10: /* Counter Register */ ret = s->reg_OSMR0 - (uint32_t)ptimer_get_count(s->ptimer); break; case 0x14: /* Status Register */ ret = s->reg_OSSR; break; case 0x1c: /* Interrupt Enable Register */ ret = s->reg_OIER; break; default: DPRINTF("Bad offset %x\n", (int)offset); } DPRINTF("offset 0x%x, value 0x%x\n", offset, ret); return ret; }
static uint32_t arm_timer_read(void *opaque, target_phys_addr_t offset) { arm_timer_state *s = (arm_timer_state *)opaque; switch (offset >> 2) { case 0: /* TimerLoad */ case 6: /* TimerBGLoad */ return s->limit; case 1: /* TimerValue */ return ptimer_get_count(s->timer); case 2: /* TimerControl */ return s->control; case 4: /* TimerRIS */ return s->int_level; case 5: /* TimerMIS */ if ((s->control & TIMER_CTRL_IE) == 0) return 0; return s->int_level; default: hw_error("%s: Bad offset %x\n", __func__, (int)offset); return 0; } }
static uint64_t digic_timer_read(void *opaque, hwaddr offset, unsigned size) { DigicTimerState *s = opaque; uint64_t ret = 0; switch (offset) { case DIGIC_TIMER_CONTROL: ret = s->control; break; case DIGIC_TIMER_RELVALUE: ret = s->relvalue; break; case DIGIC_TIMER_VALUE: ret = ptimer_get_count(s->ptimer) & 0xffff; break; default: qemu_log_mask(LOG_UNIMP, "digic-timer: read access to unknown register 0x" TARGET_FMT_plx, offset); } return ret; }
static uint32_t timer_read(void *opaque, target_phys_addr_t addr) { LM32TimerState *s = opaque; uint32_t r = 0; addr >>= 2; switch (addr) { case R_SR: case R_CR: case R_PERIOD: r = s->regs[addr]; break; case R_SNAPSHOT: r = (uint32_t)ptimer_get_count(s->ptimer); break; default: error_report("lm32_timer: read access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } trace_lm32_timer_memory_read(addr << 2, r); return r; }
static uint32_t imx_gpt_update_count(IMXGPTState *s) { s->cnt = s->next_timeout - (uint32_t)ptimer_get_count(s->timer); return s->cnt; }
uint64_t cpu_tick_get_count(void *opaque) { return -ptimer_get_count(opaque); }
static uint32_t imx_epit_update_count(IMXEPITState *s) { s->cnt = ptimer_get_count(s->timer_reload); return s->cnt; }