Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/selftests/kvm/include/arm64/arch_timer.h
49000 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
/*
3
* ARM Generic Timer specific interface
4
*/
5
6
#ifndef SELFTEST_KVM_ARCH_TIMER_H
7
#define SELFTEST_KVM_ARCH_TIMER_H
8
9
#include "processor.h"
10
11
enum arch_timer {
12
VIRTUAL,
13
PHYSICAL,
14
};
15
16
#define CTL_ENABLE (1 << 0)
17
#define CTL_IMASK (1 << 1)
18
#define CTL_ISTATUS (1 << 2)
19
20
#define msec_to_cycles(msec) \
21
(timer_get_cntfrq() * (uint64_t)(msec) / 1000)
22
23
#define usec_to_cycles(usec) \
24
(timer_get_cntfrq() * (uint64_t)(usec) / 1000000)
25
26
#define cycles_to_usec(cycles) \
27
((uint64_t)(cycles) * 1000000 / timer_get_cntfrq())
28
29
static inline uint32_t timer_get_cntfrq(void)
30
{
31
return read_sysreg(cntfrq_el0);
32
}
33
34
static inline uint64_t timer_get_cntct(enum arch_timer timer)
35
{
36
isb();
37
38
switch (timer) {
39
case VIRTUAL:
40
return read_sysreg(cntvct_el0);
41
case PHYSICAL:
42
return read_sysreg(cntpct_el0);
43
default:
44
GUEST_FAIL("Unexpected timer type = %u", timer);
45
}
46
47
/* We should not reach here */
48
return 0;
49
}
50
51
static inline void timer_set_cval(enum arch_timer timer, uint64_t cval)
52
{
53
switch (timer) {
54
case VIRTUAL:
55
write_sysreg(cval, cntv_cval_el0);
56
break;
57
case PHYSICAL:
58
write_sysreg(cval, cntp_cval_el0);
59
break;
60
default:
61
GUEST_FAIL("Unexpected timer type = %u", timer);
62
}
63
64
isb();
65
}
66
67
static inline uint64_t timer_get_cval(enum arch_timer timer)
68
{
69
switch (timer) {
70
case VIRTUAL:
71
return read_sysreg(cntv_cval_el0);
72
case PHYSICAL:
73
return read_sysreg(cntp_cval_el0);
74
default:
75
GUEST_FAIL("Unexpected timer type = %u", timer);
76
}
77
78
/* We should not reach here */
79
return 0;
80
}
81
82
static inline void timer_set_tval(enum arch_timer timer, int32_t tval)
83
{
84
switch (timer) {
85
case VIRTUAL:
86
write_sysreg(tval, cntv_tval_el0);
87
break;
88
case PHYSICAL:
89
write_sysreg(tval, cntp_tval_el0);
90
break;
91
default:
92
GUEST_FAIL("Unexpected timer type = %u", timer);
93
}
94
95
isb();
96
}
97
98
static inline int32_t timer_get_tval(enum arch_timer timer)
99
{
100
isb();
101
switch (timer) {
102
case VIRTUAL:
103
return read_sysreg(cntv_tval_el0);
104
case PHYSICAL:
105
return read_sysreg(cntp_tval_el0);
106
default:
107
GUEST_FAIL("Could not get timer %d\n", timer);
108
}
109
110
/* We should not reach here */
111
return 0;
112
}
113
114
static inline void timer_set_ctl(enum arch_timer timer, uint32_t ctl)
115
{
116
switch (timer) {
117
case VIRTUAL:
118
write_sysreg(ctl, cntv_ctl_el0);
119
break;
120
case PHYSICAL:
121
write_sysreg(ctl, cntp_ctl_el0);
122
break;
123
default:
124
GUEST_FAIL("Unexpected timer type = %u", timer);
125
}
126
127
isb();
128
}
129
130
static inline uint32_t timer_get_ctl(enum arch_timer timer)
131
{
132
switch (timer) {
133
case VIRTUAL:
134
return read_sysreg(cntv_ctl_el0);
135
case PHYSICAL:
136
return read_sysreg(cntp_ctl_el0);
137
default:
138
GUEST_FAIL("Unexpected timer type = %u", timer);
139
}
140
141
/* We should not reach here */
142
return 0;
143
}
144
145
static inline void timer_set_next_cval_ms(enum arch_timer timer, uint32_t msec)
146
{
147
uint64_t now_ct = timer_get_cntct(timer);
148
uint64_t next_ct = now_ct + msec_to_cycles(msec);
149
150
timer_set_cval(timer, next_ct);
151
}
152
153
static inline void timer_set_next_tval_ms(enum arch_timer timer, uint32_t msec)
154
{
155
timer_set_tval(timer, msec_to_cycles(msec));
156
}
157
158
static inline u32 vcpu_get_vtimer_irq(struct kvm_vcpu *vcpu)
159
{
160
u32 intid;
161
u64 attr;
162
163
attr = vcpu_has_el2(vcpu) ? KVM_ARM_VCPU_TIMER_IRQ_HVTIMER :
164
KVM_ARM_VCPU_TIMER_IRQ_VTIMER;
165
vcpu_device_attr_get(vcpu, KVM_ARM_VCPU_TIMER_CTRL, attr, &intid);
166
167
return intid;
168
}
169
170
static inline u32 vcpu_get_ptimer_irq(struct kvm_vcpu *vcpu)
171
{
172
u32 intid;
173
u64 attr;
174
175
attr = vcpu_has_el2(vcpu) ? KVM_ARM_VCPU_TIMER_IRQ_HPTIMER :
176
KVM_ARM_VCPU_TIMER_IRQ_PTIMER;
177
vcpu_device_attr_get(vcpu, KVM_ARM_VCPU_TIMER_CTRL, attr, &intid);
178
179
return intid;
180
}
181
182
#endif /* SELFTEST_KVM_ARCH_TIMER_H */
183
184