arch_timer.h 3.5 KB

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