static void timestamp_accumulate_result(struct fd_context *ctx, void *buf, union pipe_query_result *result) { struct fd5_query_sample *sp = buf; result->u64 = ticks_to_ns(ctx, sp->result); }
int domain_vtimer_init(struct domain *d, struct xen_arch_domainconfig *config) { d->arch.phys_timer_base.offset = NOW(); d->arch.virt_timer_base.offset = READ_SYSREG64(CNTPCT_EL0); d->time_offset_seconds = ticks_to_ns(d->arch.virt_timer_base.offset - boot_count); do_div(d->time_offset_seconds, 1000000000); config->clock_frequency = timer_dt_clock_frequency; /* At this stage vgic_reserve_virq can't fail */ if ( is_hardware_domain(d) ) { if ( !vgic_reserve_virq(d, timer_get_irq(TIMER_PHYS_SECURE_PPI)) ) BUG(); if ( !vgic_reserve_virq(d, timer_get_irq(TIMER_PHYS_NONSECURE_PPI)) ) BUG(); if ( !vgic_reserve_virq(d, timer_get_irq(TIMER_VIRT_PPI)) ) BUG(); } else { if ( !vgic_reserve_virq(d, GUEST_TIMER_PHYS_S_PPI) ) BUG(); if ( !vgic_reserve_virq(d, GUEST_TIMER_PHYS_NS_PPI) ) BUG(); if ( !vgic_reserve_virq(d, GUEST_TIMER_VIRT_PPI) ) BUG(); } return 0; }
static int vtimer_cntp_tval(struct cpu_user_regs *regs, uint32_t *r, int read) { struct vcpu *v = current; s_time_t now; if ( !ACCESS_ALLOWED(regs, EL0PTEN) ) return 0; now = NOW() - v->domain->arch.phys_timer_base.offset; if ( read ) { *r = (uint32_t)(ns_to_ticks(v->arch.phys_timer.cval - now) & 0xffffffffull); } else { v->arch.phys_timer.cval = now + ticks_to_ns(*r); if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE ) { v->arch.phys_timer.ctl &= ~CNTx_CTL_PENDING; set_timer(&v->arch.phys_timer.timer, v->arch.phys_timer.cval + v->domain->arch.phys_timer_base.offset); } } return 1; }
static bool vtimer_cntp_cval(struct cpu_user_regs *regs, uint64_t *r, bool read) { struct vcpu *v = current; if ( !ACCESS_ALLOWED(regs, EL0PTEN) ) return false; if ( read ) { *r = ns_to_ticks(v->arch.phys_timer.cval); } else { v->arch.phys_timer.cval = ticks_to_ns(*r); if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE ) { v->arch.phys_timer.ctl &= ~CNTx_CTL_PENDING; set_timer(&v->arch.phys_timer.timer, v->arch.phys_timer.cval + v->domain->arch.phys_timer_base.offset); } } return true; }
static int vtimer_emulate_32(struct cpu_user_regs *regs, union hsr hsr) { struct vcpu *v = current; struct hsr_cp32 cp32 = hsr.cp32; uint32_t *r = (uint32_t *)select_user_reg(regs, cp32.reg); s_time_t now; switch ( hsr.bits & HSR_CP32_REGS_MASK ) { case HSR_CPREG32(CNTP_CTL): if ( cp32.read ) { *r = v->arch.phys_timer.ctl; } else { uint32_t ctl = *r & ~CNTx_CTL_PENDING; if ( ctl & CNTx_CTL_ENABLE ) ctl |= v->arch.phys_timer.ctl & CNTx_CTL_PENDING; v->arch.phys_timer.ctl = ctl; if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE ) { set_timer(&v->arch.phys_timer.timer, v->arch.phys_timer.cval + v->domain->arch.phys_timer_base.offset); } else stop_timer(&v->arch.phys_timer.timer); } return 1; case HSR_CPREG32(CNTP_TVAL): now = NOW() - v->domain->arch.phys_timer_base.offset; if ( cp32.read ) { *r = (uint32_t)(ns_to_ticks(v->arch.phys_timer.cval - now) & 0xffffffffull); } else { v->arch.phys_timer.cval = now + ticks_to_ns(*r); if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE ) { v->arch.phys_timer.ctl &= ~CNTx_CTL_PENDING; set_timer(&v->arch.phys_timer.timer, v->arch.phys_timer.cval + v->domain->arch.phys_timer_base.offset); } } return 1; default: return 0; } }
int virt_timer_save(struct vcpu *v) { ASSERT(!is_idle_vcpu(v)); v->arch.virt_timer.ctl = READ_SYSREG32(CNTV_CTL_EL0); WRITE_SYSREG32(v->arch.virt_timer.ctl & ~CNTx_CTL_ENABLE, CNTV_CTL_EL0); v->arch.virt_timer.cval = READ_SYSREG64(CNTV_CVAL_EL0); if ( (v->arch.virt_timer.ctl & CNTx_CTL_ENABLE) && !(v->arch.virt_timer.ctl & CNTx_CTL_MASK)) { set_timer(&v->arch.virt_timer.timer, ticks_to_ns(v->arch.virt_timer.cval + v->domain->arch.virt_timer_base.offset - boot_count)); } return 0; }
int virt_timer_save(struct vcpu *v) { if ( is_idle_domain(v->domain) ) return 0; v->arch.virt_timer.ctl = READ_SYSREG32(CNTV_CTL_EL0); WRITE_SYSREG32(v->arch.virt_timer.ctl & ~CNTx_CTL_ENABLE, CNTV_CTL_EL0); v->arch.virt_timer.cval = READ_SYSREG64(CNTV_CVAL_EL0); if ( v->arch.virt_timer.ctl & CNTx_CTL_ENABLE ) { set_timer(&v->arch.virt_timer.timer, ticks_to_ns(v->arch.virt_timer.cval + v->arch.virt_timer.offset - boot_count)); } return 0; }
/* Return number of nanoseconds since boot */ s_time_t get_s_time(void) { uint64_t ticks = READ_SYSREG64(CNTPCT_EL0) - boot_count; return ticks_to_ns(ticks); }
/* monotonic_clock(): returns # of nanoseconds passed since time_init() * Note: This function is required to return accurate * time even in the absence of multiple timer ticks. */ uint64_t monotonic_clock(void) { return ticks_to_ns(read_virtual_count() - cntvct_at_init); }