xref: /OK3568_Linux_fs/kernel/include/kvm/arm_arch_timer.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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