evalsoc_common.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "nuclei_sdk_soc.h"
  2. __STATIC_FORCEINLINE uint64_t get_timer_freq(void)
  3. {
  4. return (uint64_t)SOC_TIMER_FREQ;
  5. }
  6. __STATIC_FORCEINLINE uint32_t get_time(void)
  7. {
  8. #if defined(CPU_SERIES) && CPU_SERIES == 100
  9. // NOTE: when CSR_MIRGB_INFO CSR exist and not zero, it means eclic and systimer present
  10. if (__RV_CSR_READ(CSR_MIRGB_INFO) == 0) {
  11. return __RV_CSR_READ(CSR_MTIME);
  12. }
  13. #endif
  14. return (uint32_t)SysTimer_GetLoadValue();
  15. }
  16. // optimize measure_cpu_freq function with Os/O0
  17. // to get a correct cpu frequency, which
  18. // is important for flashxip linker script
  19. #if defined ( __GNUC__ )
  20. #pragma GCC push_options
  21. #pragma GCC optimize ("Os")
  22. #elif defined ( __ICCRISCV__ )
  23. #pragma optimize=medium
  24. #endif
  25. uint32_t measure_cpu_freq(uint32_t n)
  26. {
  27. #if defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1)
  28. uint32_t start_mcycle, delta_mcycle;
  29. uint32_t start_mtime, delta_mtime;
  30. uint64_t mtime_freq = get_timer_freq();
  31. // Don't start measuruing until we see an mtime tick
  32. uint32_t tmp = (uint32_t)get_time();
  33. do {
  34. start_mtime = (uint32_t)get_time();
  35. start_mcycle = __RV_CSR_READ(CSR_MCYCLE);
  36. } while (start_mtime == tmp);
  37. do {
  38. delta_mtime = (uint32_t)get_time() - start_mtime;
  39. delta_mcycle = __RV_CSR_READ(CSR_MCYCLE) - start_mcycle;
  40. } while (delta_mtime < n);
  41. return (delta_mcycle / delta_mtime) * mtime_freq
  42. + ((delta_mcycle % delta_mtime) * mtime_freq) / delta_mtime;
  43. #else
  44. // When system timer not exist, just return 1000000Hz
  45. #warning "measure_cpu_freq function require system timer present, if you are using this, it will not work"
  46. return 1000000;
  47. #endif
  48. }
  49. #if defined ( __GNUC__ )
  50. #pragma GCC pop_options
  51. #elif defined ( __ICCRISCV__ )
  52. #endif
  53. uint32_t get_cpu_freq(void)
  54. {
  55. uint32_t cpu_freq;
  56. // warm up
  57. measure_cpu_freq(1);
  58. // measure for real
  59. #ifdef CFG_SIMULATION
  60. cpu_freq = measure_cpu_freq(5);
  61. #else
  62. cpu_freq = measure_cpu_freq(100);
  63. #endif
  64. return cpu_freq;
  65. }
  66. /**
  67. * \brief delay a time in milliseconds
  68. * \details
  69. * provide API for delay
  70. * \param[in] count: count in milliseconds
  71. * \remarks
  72. */
  73. void delay_1ms(uint32_t count)
  74. {
  75. uint64_t start_mtime, delta_mtime;
  76. uint64_t delay_ticks = (SOC_TIMER_FREQ * (uint64_t)count) / 1000;
  77. #if defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1)
  78. start_mtime = get_time();
  79. do {
  80. delta_mtime = get_time() - start_mtime;
  81. } while (delta_mtime < delay_ticks);
  82. #else
  83. #warning "delay_1ms function require system timer present, if you are using this, it will not work"
  84. #endif
  85. }
  86. void simulation_exit(int status)
  87. {
  88. // Both xlspike and qemu will write RXFIFO to make it works for xlspike even SIMU=qemu
  89. // workaround for fix cycle model exit with some message not print
  90. for (int i = 0; i < 10; i ++) {
  91. // print '\0' instead of '\r' for qemu simulation in ide
  92. uart_write(UART0, '\0');
  93. }
  94. uart_write(UART0, '\n');
  95. // pass exit status via rxfifo register
  96. SIMULATION_EXIT(status);
  97. #if defined(SIMULATION_MODE)
  98. #if SIMULATION_MODE == SIMULATION_MODE_QEMU
  99. #define QEMU_VIRT_TEST_BASE 0x100000
  100. #define QEMU_SIG_EXIT 0x3333
  101. REG32(QEMU_VIRT_TEST_BASE) = (status << 16) | QEMU_SIG_EXIT;
  102. #endif
  103. #endif
  104. }