18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2012 ARM Ltd. 48c2ecf20Sopenharmony_ci * Author: Marc Zyngier <marc.zyngier@arm.com> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef __ASM_ARM_KVM_ARCH_TIMER_H 88c2ecf20Sopenharmony_ci#define __ASM_ARM_KVM_ARCH_TIMER_H 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/clocksource.h> 118c2ecf20Sopenharmony_ci#include <linux/hrtimer.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_cienum kvm_arch_timers { 148c2ecf20Sopenharmony_ci TIMER_PTIMER, 158c2ecf20Sopenharmony_ci TIMER_VTIMER, 168c2ecf20Sopenharmony_ci NR_KVM_TIMERS 178c2ecf20Sopenharmony_ci}; 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cienum kvm_arch_timer_regs { 208c2ecf20Sopenharmony_ci TIMER_REG_CNT, 218c2ecf20Sopenharmony_ci TIMER_REG_CVAL, 228c2ecf20Sopenharmony_ci TIMER_REG_TVAL, 238c2ecf20Sopenharmony_ci TIMER_REG_CTL, 248c2ecf20Sopenharmony_ci}; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistruct arch_timer_context { 278c2ecf20Sopenharmony_ci struct kvm_vcpu *vcpu; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci /* Timer IRQ */ 308c2ecf20Sopenharmony_ci struct kvm_irq_level irq; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci /* Emulated Timer (may be unused) */ 338c2ecf20Sopenharmony_ci struct hrtimer hrtimer; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci /* 368c2ecf20Sopenharmony_ci * We have multiple paths which can save/restore the timer state onto 378c2ecf20Sopenharmony_ci * the hardware, so we need some way of keeping track of where the 388c2ecf20Sopenharmony_ci * latest state is. 398c2ecf20Sopenharmony_ci */ 408c2ecf20Sopenharmony_ci bool loaded; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci /* Duplicated state from arch_timer.c for convenience */ 438c2ecf20Sopenharmony_ci u32 host_timer_irq; 448c2ecf20Sopenharmony_ci u32 host_timer_irq_flags; 458c2ecf20Sopenharmony_ci}; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistruct timer_map { 488c2ecf20Sopenharmony_ci struct arch_timer_context *direct_vtimer; 498c2ecf20Sopenharmony_ci struct arch_timer_context *direct_ptimer; 508c2ecf20Sopenharmony_ci struct arch_timer_context *emul_ptimer; 518c2ecf20Sopenharmony_ci}; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistruct arch_timer_cpu { 548c2ecf20Sopenharmony_ci struct arch_timer_context timers[NR_KVM_TIMERS]; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci /* Background timer used when the guest is not running */ 578c2ecf20Sopenharmony_ci struct hrtimer bg_timer; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci /* Is the timer enabled */ 608c2ecf20Sopenharmony_ci bool enabled; 618c2ecf20Sopenharmony_ci}; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ciint kvm_timer_hyp_init(bool); 648c2ecf20Sopenharmony_ciint kvm_timer_enable(struct kvm_vcpu *vcpu); 658c2ecf20Sopenharmony_ciint kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu); 668c2ecf20Sopenharmony_civoid kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); 678c2ecf20Sopenharmony_civoid kvm_timer_sync_user(struct kvm_vcpu *vcpu); 688c2ecf20Sopenharmony_cibool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu); 698c2ecf20Sopenharmony_civoid kvm_timer_update_run(struct kvm_vcpu *vcpu); 708c2ecf20Sopenharmony_civoid kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu); 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ciu64 kvm_arm_timer_get_reg(struct kvm_vcpu *, u64 regid); 738c2ecf20Sopenharmony_ciint kvm_arm_timer_set_reg(struct kvm_vcpu *, u64 regid, u64 value); 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ciint kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); 768c2ecf20Sopenharmony_ciint kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); 778c2ecf20Sopenharmony_ciint kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cibool kvm_timer_is_pending(struct kvm_vcpu *vcpu); 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ciu64 kvm_phys_timer_read(void); 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_civoid kvm_timer_vcpu_load(struct kvm_vcpu *vcpu); 848c2ecf20Sopenharmony_civoid kvm_timer_vcpu_put(struct kvm_vcpu *vcpu); 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_civoid kvm_timer_init_vhe(void); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cibool kvm_arch_timer_get_input_level(int vintid); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci#define vcpu_timer(v) (&(v)->arch.timer_cpu) 918c2ecf20Sopenharmony_ci#define vcpu_get_timer(v,t) (&vcpu_timer(v)->timers[(t)]) 928c2ecf20Sopenharmony_ci#define vcpu_vtimer(v) (&(v)->arch.timer_cpu.timers[TIMER_VTIMER]) 938c2ecf20Sopenharmony_ci#define vcpu_ptimer(v) (&(v)->arch.timer_cpu.timers[TIMER_PTIMER]) 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci#define arch_timer_ctx_index(ctx) ((ctx) - vcpu_timer((ctx)->vcpu)->timers) 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ciu64 kvm_arm_timer_read_sysreg(struct kvm_vcpu *vcpu, 988c2ecf20Sopenharmony_ci enum kvm_arch_timers tmr, 998c2ecf20Sopenharmony_ci enum kvm_arch_timer_regs treg); 1008c2ecf20Sopenharmony_civoid kvm_arm_timer_write_sysreg(struct kvm_vcpu *vcpu, 1018c2ecf20Sopenharmony_ci enum kvm_arch_timers tmr, 1028c2ecf20Sopenharmony_ci enum kvm_arch_timer_regs treg, 1038c2ecf20Sopenharmony_ci u64 val); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci/* Needed for tracing */ 1068c2ecf20Sopenharmony_ciu32 timer_get_ctl(struct arch_timer_context *ctxt); 1078c2ecf20Sopenharmony_ciu64 timer_get_cval(struct arch_timer_context *ctxt); 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci#endif 110