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