Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * ARM Generic Timer specific interface
0004  */
0005 
0006 #ifndef SELFTEST_KVM_ARCH_TIMER_H
0007 #define SELFTEST_KVM_ARCH_TIMER_H
0008 
0009 #include "processor.h"
0010 
0011 enum arch_timer {
0012     VIRTUAL,
0013     PHYSICAL,
0014 };
0015 
0016 #define CTL_ENABLE  (1 << 0)
0017 #define CTL_IMASK   (1 << 1)
0018 #define CTL_ISTATUS (1 << 2)
0019 
0020 #define msec_to_cycles(msec)    \
0021     (timer_get_cntfrq() * (uint64_t)(msec) / 1000)
0022 
0023 #define usec_to_cycles(usec)    \
0024     (timer_get_cntfrq() * (uint64_t)(usec) / 1000000)
0025 
0026 #define cycles_to_usec(cycles) \
0027     ((uint64_t)(cycles) * 1000000 / timer_get_cntfrq())
0028 
0029 static inline uint32_t timer_get_cntfrq(void)
0030 {
0031     return read_sysreg(cntfrq_el0);
0032 }
0033 
0034 static inline uint64_t timer_get_cntct(enum arch_timer timer)
0035 {
0036     isb();
0037 
0038     switch (timer) {
0039     case VIRTUAL:
0040         return read_sysreg(cntvct_el0);
0041     case PHYSICAL:
0042         return read_sysreg(cntpct_el0);
0043     default:
0044         GUEST_ASSERT_1(0, timer);
0045     }
0046 
0047     /* We should not reach here */
0048     return 0;
0049 }
0050 
0051 static inline void timer_set_cval(enum arch_timer timer, uint64_t cval)
0052 {
0053     switch (timer) {
0054     case VIRTUAL:
0055         write_sysreg(cval, cntv_cval_el0);
0056         break;
0057     case PHYSICAL:
0058         write_sysreg(cval, cntp_cval_el0);
0059         break;
0060     default:
0061         GUEST_ASSERT_1(0, timer);
0062     }
0063 
0064     isb();
0065 }
0066 
0067 static inline uint64_t timer_get_cval(enum arch_timer timer)
0068 {
0069     switch (timer) {
0070     case VIRTUAL:
0071         return read_sysreg(cntv_cval_el0);
0072     case PHYSICAL:
0073         return read_sysreg(cntp_cval_el0);
0074     default:
0075         GUEST_ASSERT_1(0, timer);
0076     }
0077 
0078     /* We should not reach here */
0079     return 0;
0080 }
0081 
0082 static inline void timer_set_tval(enum arch_timer timer, uint32_t tval)
0083 {
0084     switch (timer) {
0085     case VIRTUAL:
0086         write_sysreg(tval, cntv_tval_el0);
0087         break;
0088     case PHYSICAL:
0089         write_sysreg(tval, cntp_tval_el0);
0090         break;
0091     default:
0092         GUEST_ASSERT_1(0, timer);
0093     }
0094 
0095     isb();
0096 }
0097 
0098 static inline void timer_set_ctl(enum arch_timer timer, uint32_t ctl)
0099 {
0100     switch (timer) {
0101     case VIRTUAL:
0102         write_sysreg(ctl, cntv_ctl_el0);
0103         break;
0104     case PHYSICAL:
0105         write_sysreg(ctl, cntp_ctl_el0);
0106         break;
0107     default:
0108         GUEST_ASSERT_1(0, timer);
0109     }
0110 
0111     isb();
0112 }
0113 
0114 static inline uint32_t timer_get_ctl(enum arch_timer timer)
0115 {
0116     switch (timer) {
0117     case VIRTUAL:
0118         return read_sysreg(cntv_ctl_el0);
0119     case PHYSICAL:
0120         return read_sysreg(cntp_ctl_el0);
0121     default:
0122         GUEST_ASSERT_1(0, timer);
0123     }
0124 
0125     /* We should not reach here */
0126     return 0;
0127 }
0128 
0129 static inline void timer_set_next_cval_ms(enum arch_timer timer, uint32_t msec)
0130 {
0131     uint64_t now_ct = timer_get_cntct(timer);
0132     uint64_t next_ct = now_ct + msec_to_cycles(msec);
0133 
0134     timer_set_cval(timer, next_ct);
0135 }
0136 
0137 static inline void timer_set_next_tval_ms(enum arch_timer timer, uint32_t msec)
0138 {
0139     timer_set_tval(timer, msec_to_cycles(msec));
0140 }
0141 
0142 #endif /* SELFTEST_KVM_ARCH_TIMER_H */