arch_timer.h (2646B)
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 11enum 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 29static inline uint32_t timer_get_cntfrq(void) 30{ 31 return read_sysreg(cntfrq_el0); 32} 33 34static 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_ASSERT_1(0, timer); 45 } 46 47 /* We should not reach here */ 48 return 0; 49} 50 51static 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_ASSERT_1(0, timer); 62 } 63 64 isb(); 65} 66 67static 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_ASSERT_1(0, timer); 76 } 77 78 /* We should not reach here */ 79 return 0; 80} 81 82static inline void timer_set_tval(enum arch_timer timer, uint32_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_ASSERT_1(0, timer); 93 } 94 95 isb(); 96} 97 98static inline void timer_set_ctl(enum arch_timer timer, uint32_t ctl) 99{ 100 switch (timer) { 101 case VIRTUAL: 102 write_sysreg(ctl, cntv_ctl_el0); 103 break; 104 case PHYSICAL: 105 write_sysreg(ctl, cntp_ctl_el0); 106 break; 107 default: 108 GUEST_ASSERT_1(0, timer); 109 } 110 111 isb(); 112} 113 114static inline uint32_t timer_get_ctl(enum arch_timer timer) 115{ 116 switch (timer) { 117 case VIRTUAL: 118 return read_sysreg(cntv_ctl_el0); 119 case PHYSICAL: 120 return read_sysreg(cntp_ctl_el0); 121 default: 122 GUEST_ASSERT_1(0, timer); 123 } 124 125 /* We should not reach here */ 126 return 0; 127} 128 129static inline void timer_set_next_cval_ms(enum arch_timer timer, uint32_t msec) 130{ 131 uint64_t now_ct = timer_get_cntct(timer); 132 uint64_t next_ct = now_ct + msec_to_cycles(msec); 133 134 timer_set_cval(timer, next_ct); 135} 136 137static inline void timer_set_next_tval_ms(enum arch_timer timer, uint32_t msec) 138{ 139 timer_set_tval(timer, msec_to_cycles(msec)); 140} 141 142#endif /* SELFTEST_KVM_ARCH_TIMER_H */