AArch64 EL2 hypervisor for QEMU virt that boots at EL2
1

Configure Feed

Select the types of activity you want to include in your feed.

ariel / drivers / timer.c
1.2 kB 54 lines
1#include "hv/arch.h" 2#include "hv/config.h" 3#include "hv/timer.h" 4#include "hv/uart.h" 5#include "hv/vcpu.h" 6 7static uint64_t g_cntfrq; 8 9void timer_init(void) 10{ 11 g_cntfrq = arch_cntfrq_el0(); 12} 13 14uint64_t timer_now(void) 15{ 16 return arch_cntpct_el0(); 17} 18 19void timer_dump(void) 20{ 21 uart_puts("timer cntfrq="); 22 uart_put_dec64(g_cntfrq); 23 uart_puts(" cntpct="); 24 uart_put_dec64(timer_now()); 25 uart_puts("\n"); 26} 27 28void timer_vcpu_sync(struct vcpu *vcpu) 29{ 30 uint64_t now; 31 if (vcpu == (struct vcpu *)0) { 32 return; 33 } 34 35 vcpu->stats.timer_syncs++; 36 now = timer_now(); 37 uint64_t ctl = vcpu->sysregs.cntv_ctl_el0; 38 bool enabled = (ctl & 1u) != 0u; 39 bool masked = (ctl & 2u) != 0u; 40 if (!enabled || masked) { 41 vcpu_clear_pending_irq(vcpu, CONFIG_VTIMER_IRQ); 42 return; 43 } 44 45 if (now >= vcpu->sysregs.cntv_cval_el0) { 46 vcpu->stats.timer_last_delta = now - vcpu->sysregs.cntv_cval_el0; 47 vcpu->sysregs.cntv_ctl_el0 |= 4u; 48 vcpu_set_pending_irq(vcpu, CONFIG_VTIMER_IRQ); 49 } else { 50 vcpu->stats.timer_last_delta = vcpu->sysregs.cntv_cval_el0 - now; 51 vcpu->sysregs.cntv_ctl_el0 &= ~4ull; 52 vcpu_clear_pending_irq(vcpu, CONFIG_VTIMER_IRQ); 53 } 54}