1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) 2012 ARM Ltd. 4*4882a593Smuzhiyun * Author: Marc Zyngier <marc.zyngier@arm.com> 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #ifndef __ASM_ARM_KVM_ARCH_TIMER_H 8*4882a593Smuzhiyun #define __ASM_ARM_KVM_ARCH_TIMER_H 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #include <linux/clocksource.h> 11*4882a593Smuzhiyun #include <linux/hrtimer.h> 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun enum kvm_arch_timers { 14*4882a593Smuzhiyun TIMER_PTIMER, 15*4882a593Smuzhiyun TIMER_VTIMER, 16*4882a593Smuzhiyun NR_KVM_TIMERS 17*4882a593Smuzhiyun }; 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun enum kvm_arch_timer_regs { 20*4882a593Smuzhiyun TIMER_REG_CNT, 21*4882a593Smuzhiyun TIMER_REG_CVAL, 22*4882a593Smuzhiyun TIMER_REG_TVAL, 23*4882a593Smuzhiyun TIMER_REG_CTL, 24*4882a593Smuzhiyun }; 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun struct arch_timer_context { 27*4882a593Smuzhiyun struct kvm_vcpu *vcpu; 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun /* Timer IRQ */ 30*4882a593Smuzhiyun struct kvm_irq_level irq; 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun /* Emulated Timer (may be unused) */ 33*4882a593Smuzhiyun struct hrtimer hrtimer; 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun /* 36*4882a593Smuzhiyun * We have multiple paths which can save/restore the timer state onto 37*4882a593Smuzhiyun * the hardware, so we need some way of keeping track of where the 38*4882a593Smuzhiyun * latest state is. 39*4882a593Smuzhiyun */ 40*4882a593Smuzhiyun bool loaded; 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun /* Duplicated state from arch_timer.c for convenience */ 43*4882a593Smuzhiyun u32 host_timer_irq; 44*4882a593Smuzhiyun u32 host_timer_irq_flags; 45*4882a593Smuzhiyun }; 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun struct timer_map { 48*4882a593Smuzhiyun struct arch_timer_context *direct_vtimer; 49*4882a593Smuzhiyun struct arch_timer_context *direct_ptimer; 50*4882a593Smuzhiyun struct arch_timer_context *emul_ptimer; 51*4882a593Smuzhiyun }; 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun struct arch_timer_cpu { 54*4882a593Smuzhiyun struct arch_timer_context timers[NR_KVM_TIMERS]; 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun /* Background timer used when the guest is not running */ 57*4882a593Smuzhiyun struct hrtimer bg_timer; 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun /* Is the timer enabled */ 60*4882a593Smuzhiyun bool enabled; 61*4882a593Smuzhiyun }; 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun int kvm_timer_hyp_init(bool); 64*4882a593Smuzhiyun int kvm_timer_enable(struct kvm_vcpu *vcpu); 65*4882a593Smuzhiyun int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu); 66*4882a593Smuzhiyun void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); 67*4882a593Smuzhiyun void kvm_timer_sync_user(struct kvm_vcpu *vcpu); 68*4882a593Smuzhiyun bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu); 69*4882a593Smuzhiyun void kvm_timer_update_run(struct kvm_vcpu *vcpu); 70*4882a593Smuzhiyun void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu); 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun u64 kvm_arm_timer_get_reg(struct kvm_vcpu *, u64 regid); 73*4882a593Smuzhiyun int kvm_arm_timer_set_reg(struct kvm_vcpu *, u64 regid, u64 value); 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); 76*4882a593Smuzhiyun int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); 77*4882a593Smuzhiyun int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun bool kvm_timer_is_pending(struct kvm_vcpu *vcpu); 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun u64 kvm_phys_timer_read(void); 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu); 84*4882a593Smuzhiyun void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu); 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun void kvm_timer_init_vhe(void); 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun bool kvm_arch_timer_get_input_level(int vintid); 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun #define vcpu_timer(v) (&(v)->arch.timer_cpu) 91*4882a593Smuzhiyun #define vcpu_get_timer(v,t) (&vcpu_timer(v)->timers[(t)]) 92*4882a593Smuzhiyun #define vcpu_vtimer(v) (&(v)->arch.timer_cpu.timers[TIMER_VTIMER]) 93*4882a593Smuzhiyun #define vcpu_ptimer(v) (&(v)->arch.timer_cpu.timers[TIMER_PTIMER]) 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun #define arch_timer_ctx_index(ctx) ((ctx) - vcpu_timer((ctx)->vcpu)->timers) 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun u64 kvm_arm_timer_read_sysreg(struct kvm_vcpu *vcpu, 98*4882a593Smuzhiyun enum kvm_arch_timers tmr, 99*4882a593Smuzhiyun enum kvm_arch_timer_regs treg); 100*4882a593Smuzhiyun void kvm_arm_timer_write_sysreg(struct kvm_vcpu *vcpu, 101*4882a593Smuzhiyun enum kvm_arch_timers tmr, 102*4882a593Smuzhiyun enum kvm_arch_timer_regs treg, 103*4882a593Smuzhiyun u64 val); 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun /* Needed for tracing */ 106*4882a593Smuzhiyun u32 timer_get_ctl(struct arch_timer_context *ctxt); 107*4882a593Smuzhiyun u64 timer_get_cval(struct arch_timer_context *ctxt); 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun #endif 110