evalsoc_common.c 3.0 KB

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