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