Beispiel #1
0
void generic_timer_vcpu_context_save(struct generic_timer_context *cntx)
{
	cntx->cntpctl = generic_timer_reg_read(GENERIC_TIMER_REG_PHYS_CTRL);
	cntx->cntvctl = generic_timer_reg_read(GENERIC_TIMER_REG_VIRT_CTRL);
	cntx->cntpcval = generic_timer_reg_read64(GENERIC_TIMER_REG_PHYS_CVAL);
	cntx->cntvcval = generic_timer_reg_read64(GENERIC_TIMER_REG_VIRT_CVAL);
	cntx->cntkctl = generic_timer_reg_read(GENERIC_TIMER_REG_KCTL);
	generic_timer_reg_write(GENERIC_TIMER_REG_PHYS_CTRL, 
				GENERIC_TIMER_CTRL_IT_MASK);
	generic_timer_reg_write(GENERIC_TIMER_REG_VIRT_CTRL, 
				GENERIC_TIMER_CTRL_IT_MASK);
}
void generic_timer_vcpu_context_save(void *vcpu_ptr, void *context)
{
	u64 ev_nsecs;
	struct generic_timer_context *cntx = context;

	if (!cntx) {
		return;
	}

#ifdef HAVE_GENERIC_TIMER_REGS_SAVE
	generic_timer_regs_save(cntx);
#else
	cntx->cntpctl = generic_timer_reg_read(GENERIC_TIMER_REG_PHYS_CTRL);
	cntx->cntvctl = generic_timer_reg_read(GENERIC_TIMER_REG_VIRT_CTRL);
	cntx->cntpcval = generic_timer_reg_read64(GENERIC_TIMER_REG_PHYS_CVAL);
	cntx->cntvcval = generic_timer_reg_read64(GENERIC_TIMER_REG_VIRT_CVAL);
	cntx->cntkctl = generic_timer_reg_read(GENERIC_TIMER_REG_KCTL);
	generic_timer_reg_write(GENERIC_TIMER_REG_PHYS_CTRL,
				GENERIC_TIMER_CTRL_IT_MASK);
	generic_timer_reg_write(GENERIC_TIMER_REG_VIRT_CTRL,
				GENERIC_TIMER_CTRL_IT_MASK);
#endif

	if ((cntx->cntpctl & GENERIC_TIMER_CTRL_ENABLE) &&
	    !(cntx->cntpctl & GENERIC_TIMER_CTRL_IT_MASK)) {
		ev_nsecs = cntx->cntpcval - generic_timer_pcounter_read();
		/* check if timer is expired while saving the context */
		if (((s64)ev_nsecs) < 0) {
			ev_nsecs = 0;
		} else {
			ev_nsecs = vmm_clocksource_delta2nsecs(ev_nsecs,
							generic_timer_mult,
							generic_timer_shift);
		}
		vmm_timer_event_start(&cntx->phys_ev, ev_nsecs);
	}

	if ((cntx->cntvctl & GENERIC_TIMER_CTRL_ENABLE) &&
	    !(cntx->cntvctl & GENERIC_TIMER_CTRL_IT_MASK)) {
		ev_nsecs = cntx->cntvcval + cntx->cntvoff -
					generic_timer_pcounter_read();
		/* check if timer is expired while saving the context */
		if (((s64)ev_nsecs) < 0) {
			ev_nsecs = 0;
		} else {
			ev_nsecs = vmm_clocksource_delta2nsecs(ev_nsecs,
							generic_timer_mult,
							generic_timer_shift);
		}
		vmm_timer_event_start(&cntx->virt_ev, ev_nsecs);
	}
}