drv_gtimer.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <rtthread.h>
  7. #include "interrupt.h"
  8. #ifndef RT_CPUS_NR
  9. #define RT_CPUS_NR 1
  10. #endif
  11. #define GTIMER_IRQ (27)
  12. static uint64_t _tickval[RT_CPUS_NR];
  13. static uint64_t _increaseval[RT_CPUS_NR];
  14. #define tickval _tickval[cpu_id]
  15. #define increaseval _increaseval[cpu_id]
  16. /**
  17. * This function is the gtimer isr handler.
  18. *
  19. * @param vector interrupt ID
  20. * @param parameter the parameter specified by rt_hw_interrupt_install
  21. *
  22. * @return none
  23. */
  24. static void _hw_timer_isr(int vector, void *parameter)
  25. {
  26. #ifdef RT_USING_SMP
  27. int cpu_id = rt_hw_cpu_id();
  28. #else
  29. int cpu_id = 0;
  30. #endif
  31. uint64_t cntvct_el0;
  32. do
  33. {
  34. tickval += increaseval;
  35. __asm__ volatile("msr CNTV_CVAL_EL0, %0"::"r"(tickval));
  36. __asm__ volatile("mrs %0, CNTVCT_EL0":"=r"(cntvct_el0));
  37. } while (cntvct_el0 >= tickval);
  38. rt_tick_increase();
  39. }
  40. /**
  41. * The function will initialize the general timer used for the system tick.
  42. *
  43. * @param none
  44. *
  45. * @return none
  46. */
  47. rt_weak int rt_hw_gtimer_init(void)
  48. {
  49. #ifdef RT_USING_SMP
  50. int cpu_id = rt_hw_cpu_id();
  51. #else
  52. int cpu_id = 0;
  53. #endif
  54. uint64_t val;
  55. rt_hw_interrupt_install(GTIMER_IRQ, _hw_timer_isr, RT_NULL, "tick");
  56. rt_hw_interrupt_umask(GTIMER_IRQ);
  57. __asm__ volatile("mrs %0, CNTFRQ_EL0":"=r"(val));
  58. increaseval = val / RT_TICK_PER_SECOND;
  59. __asm__ volatile("msr CNTV_CTL_EL0, %0"::"r"(val));
  60. tickval = increaseval;
  61. __asm__ volatile("msr CNTV_CVAL_EL0, %0"::"r"(tickval));
  62. val = 1;
  63. __asm__ volatile("msr CNTV_CTL_EL0, %0"::"r"(val));
  64. return 0;
  65. }
  66. INIT_BOARD_EXPORT(rt_hw_gtimer_init);