xref: /openbmc/linux/tools/testing/selftests/kvm/include/aarch64/arch_timer.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1d977ed39SRaghavendra Rao Ananta /* SPDX-License-Identifier: GPL-2.0 */
2d977ed39SRaghavendra Rao Ananta /*
3d977ed39SRaghavendra Rao Ananta  * ARM Generic Timer specific interface
4d977ed39SRaghavendra Rao Ananta  */
5d977ed39SRaghavendra Rao Ananta 
6d977ed39SRaghavendra Rao Ananta #ifndef SELFTEST_KVM_ARCH_TIMER_H
7d977ed39SRaghavendra Rao Ananta #define SELFTEST_KVM_ARCH_TIMER_H
8d977ed39SRaghavendra Rao Ananta 
9d977ed39SRaghavendra Rao Ananta #include "processor.h"
10d977ed39SRaghavendra Rao Ananta 
11d977ed39SRaghavendra Rao Ananta enum arch_timer {
12d977ed39SRaghavendra Rao Ananta 	VIRTUAL,
13d977ed39SRaghavendra Rao Ananta 	PHYSICAL,
14d977ed39SRaghavendra Rao Ananta };
15d977ed39SRaghavendra Rao Ananta 
16d977ed39SRaghavendra Rao Ananta #define CTL_ENABLE	(1 << 0)
17d977ed39SRaghavendra Rao Ananta #define CTL_IMASK	(1 << 1)
18d977ed39SRaghavendra Rao Ananta #define CTL_ISTATUS	(1 << 2)
19d977ed39SRaghavendra Rao Ananta 
20d977ed39SRaghavendra Rao Ananta #define msec_to_cycles(msec)	\
21d977ed39SRaghavendra Rao Ananta 	(timer_get_cntfrq() * (uint64_t)(msec) / 1000)
22d977ed39SRaghavendra Rao Ananta 
23d977ed39SRaghavendra Rao Ananta #define usec_to_cycles(usec)	\
24d977ed39SRaghavendra Rao Ananta 	(timer_get_cntfrq() * (uint64_t)(usec) / 1000000)
25d977ed39SRaghavendra Rao Ananta 
26d977ed39SRaghavendra Rao Ananta #define cycles_to_usec(cycles) \
27d977ed39SRaghavendra Rao Ananta 	((uint64_t)(cycles) * 1000000 / timer_get_cntfrq())
28d977ed39SRaghavendra Rao Ananta 
timer_get_cntfrq(void)29d977ed39SRaghavendra Rao Ananta static inline uint32_t timer_get_cntfrq(void)
30d977ed39SRaghavendra Rao Ananta {
31d977ed39SRaghavendra Rao Ananta 	return read_sysreg(cntfrq_el0);
32d977ed39SRaghavendra Rao Ananta }
33d977ed39SRaghavendra Rao Ananta 
timer_get_cntct(enum arch_timer timer)34d977ed39SRaghavendra Rao Ananta static inline uint64_t timer_get_cntct(enum arch_timer timer)
35d977ed39SRaghavendra Rao Ananta {
36d977ed39SRaghavendra Rao Ananta 	isb();
37d977ed39SRaghavendra Rao Ananta 
38d977ed39SRaghavendra Rao Ananta 	switch (timer) {
39d977ed39SRaghavendra Rao Ananta 	case VIRTUAL:
40d977ed39SRaghavendra Rao Ananta 		return read_sysreg(cntvct_el0);
41d977ed39SRaghavendra Rao Ananta 	case PHYSICAL:
42d977ed39SRaghavendra Rao Ananta 		return read_sysreg(cntpct_el0);
43d977ed39SRaghavendra Rao Ananta 	default:
44*a05c4c2bSSean Christopherson 		GUEST_FAIL("Unexpected timer type = %u", timer);
45d977ed39SRaghavendra Rao Ananta 	}
46d977ed39SRaghavendra Rao Ananta 
47d977ed39SRaghavendra Rao Ananta 	/* We should not reach here */
48d977ed39SRaghavendra Rao Ananta 	return 0;
49d977ed39SRaghavendra Rao Ananta }
50d977ed39SRaghavendra Rao Ananta 
timer_set_cval(enum arch_timer timer,uint64_t cval)51d977ed39SRaghavendra Rao Ananta static inline void timer_set_cval(enum arch_timer timer, uint64_t cval)
52d977ed39SRaghavendra Rao Ananta {
53d977ed39SRaghavendra Rao Ananta 	switch (timer) {
54d977ed39SRaghavendra Rao Ananta 	case VIRTUAL:
55d977ed39SRaghavendra Rao Ananta 		write_sysreg(cval, cntv_cval_el0);
56d977ed39SRaghavendra Rao Ananta 		break;
57d977ed39SRaghavendra Rao Ananta 	case PHYSICAL:
58d977ed39SRaghavendra Rao Ananta 		write_sysreg(cval, cntp_cval_el0);
59d977ed39SRaghavendra Rao Ananta 		break;
60d977ed39SRaghavendra Rao Ananta 	default:
61*a05c4c2bSSean Christopherson 		GUEST_FAIL("Unexpected timer type = %u", timer);
62d977ed39SRaghavendra Rao Ananta 	}
63d977ed39SRaghavendra Rao Ananta 
64d977ed39SRaghavendra Rao Ananta 	isb();
65d977ed39SRaghavendra Rao Ananta }
66d977ed39SRaghavendra Rao Ananta 
timer_get_cval(enum arch_timer timer)67d977ed39SRaghavendra Rao Ananta static inline uint64_t timer_get_cval(enum arch_timer timer)
68d977ed39SRaghavendra Rao Ananta {
69d977ed39SRaghavendra Rao Ananta 	switch (timer) {
70d977ed39SRaghavendra Rao Ananta 	case VIRTUAL:
71d977ed39SRaghavendra Rao Ananta 		return read_sysreg(cntv_cval_el0);
72d977ed39SRaghavendra Rao Ananta 	case PHYSICAL:
73d977ed39SRaghavendra Rao Ananta 		return read_sysreg(cntp_cval_el0);
74d977ed39SRaghavendra Rao Ananta 	default:
75*a05c4c2bSSean Christopherson 		GUEST_FAIL("Unexpected timer type = %u", timer);
76d977ed39SRaghavendra Rao Ananta 	}
77d977ed39SRaghavendra Rao Ananta 
78d977ed39SRaghavendra Rao Ananta 	/* We should not reach here */
79d977ed39SRaghavendra Rao Ananta 	return 0;
80d977ed39SRaghavendra Rao Ananta }
81d977ed39SRaghavendra Rao Ananta 
timer_set_tval(enum arch_timer timer,uint32_t tval)82d977ed39SRaghavendra Rao Ananta static inline void timer_set_tval(enum arch_timer timer, uint32_t tval)
83d977ed39SRaghavendra Rao Ananta {
84d977ed39SRaghavendra Rao Ananta 	switch (timer) {
85d977ed39SRaghavendra Rao Ananta 	case VIRTUAL:
86d977ed39SRaghavendra Rao Ananta 		write_sysreg(tval, cntv_tval_el0);
87d977ed39SRaghavendra Rao Ananta 		break;
88d977ed39SRaghavendra Rao Ananta 	case PHYSICAL:
89d977ed39SRaghavendra Rao Ananta 		write_sysreg(tval, cntp_tval_el0);
90d977ed39SRaghavendra Rao Ananta 		break;
91d977ed39SRaghavendra Rao Ananta 	default:
92*a05c4c2bSSean Christopherson 		GUEST_FAIL("Unexpected timer type = %u", timer);
93d977ed39SRaghavendra Rao Ananta 	}
94d977ed39SRaghavendra Rao Ananta 
95d977ed39SRaghavendra Rao Ananta 	isb();
96d977ed39SRaghavendra Rao Ananta }
97d977ed39SRaghavendra Rao Ananta 
timer_set_ctl(enum arch_timer timer,uint32_t ctl)98d977ed39SRaghavendra Rao Ananta static inline void timer_set_ctl(enum arch_timer timer, uint32_t ctl)
99d977ed39SRaghavendra Rao Ananta {
100d977ed39SRaghavendra Rao Ananta 	switch (timer) {
101d977ed39SRaghavendra Rao Ananta 	case VIRTUAL:
102d977ed39SRaghavendra Rao Ananta 		write_sysreg(ctl, cntv_ctl_el0);
103d977ed39SRaghavendra Rao Ananta 		break;
104d977ed39SRaghavendra Rao Ananta 	case PHYSICAL:
105d977ed39SRaghavendra Rao Ananta 		write_sysreg(ctl, cntp_ctl_el0);
106d977ed39SRaghavendra Rao Ananta 		break;
107d977ed39SRaghavendra Rao Ananta 	default:
108*a05c4c2bSSean Christopherson 		GUEST_FAIL("Unexpected timer type = %u", timer);
109d977ed39SRaghavendra Rao Ananta 	}
110d977ed39SRaghavendra Rao Ananta 
111d977ed39SRaghavendra Rao Ananta 	isb();
112d977ed39SRaghavendra Rao Ananta }
113d977ed39SRaghavendra Rao Ananta 
timer_get_ctl(enum arch_timer timer)114d977ed39SRaghavendra Rao Ananta static inline uint32_t timer_get_ctl(enum arch_timer timer)
115d977ed39SRaghavendra Rao Ananta {
116d977ed39SRaghavendra Rao Ananta 	switch (timer) {
117d977ed39SRaghavendra Rao Ananta 	case VIRTUAL:
118d977ed39SRaghavendra Rao Ananta 		return read_sysreg(cntv_ctl_el0);
119d977ed39SRaghavendra Rao Ananta 	case PHYSICAL:
120d977ed39SRaghavendra Rao Ananta 		return read_sysreg(cntp_ctl_el0);
121d977ed39SRaghavendra Rao Ananta 	default:
122*a05c4c2bSSean Christopherson 		GUEST_FAIL("Unexpected timer type = %u", timer);
123d977ed39SRaghavendra Rao Ananta 	}
124d977ed39SRaghavendra Rao Ananta 
125d977ed39SRaghavendra Rao Ananta 	/* We should not reach here */
126d977ed39SRaghavendra Rao Ananta 	return 0;
127d977ed39SRaghavendra Rao Ananta }
128d977ed39SRaghavendra Rao Ananta 
timer_set_next_cval_ms(enum arch_timer timer,uint32_t msec)129d977ed39SRaghavendra Rao Ananta static inline void timer_set_next_cval_ms(enum arch_timer timer, uint32_t msec)
130d977ed39SRaghavendra Rao Ananta {
131d977ed39SRaghavendra Rao Ananta 	uint64_t now_ct = timer_get_cntct(timer);
132d977ed39SRaghavendra Rao Ananta 	uint64_t next_ct = now_ct + msec_to_cycles(msec);
133d977ed39SRaghavendra Rao Ananta 
134d977ed39SRaghavendra Rao Ananta 	timer_set_cval(timer, next_ct);
135d977ed39SRaghavendra Rao Ananta }
136d977ed39SRaghavendra Rao Ananta 
timer_set_next_tval_ms(enum arch_timer timer,uint32_t msec)137d977ed39SRaghavendra Rao Ananta static inline void timer_set_next_tval_ms(enum arch_timer timer, uint32_t msec)
138d977ed39SRaghavendra Rao Ananta {
139d977ed39SRaghavendra Rao Ananta 	timer_set_tval(timer, msec_to_cycles(msec));
140d977ed39SRaghavendra Rao Ananta }
141d977ed39SRaghavendra Rao Ananta 
142d977ed39SRaghavendra Rao Ananta #endif /* SELFTEST_KVM_ARCH_TIMER_H */
143