hpm_csr_drv.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * Copyright (c) 2023 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_CSR_DRV_H
  8. #define HPM_CSR_DRV_H
  9. #include "hpm_csr_regs.h"
  10. #include "riscv/riscv_core.h"
  11. /**
  12. * @brief CSR driver APIs
  13. * @defgroup csr_interface CSR driver APIs
  14. * @ingroup csr_interfaces
  15. * @{
  16. *
  17. */
  18. #ifdef __cplusplus
  19. extern "C" {
  20. #endif
  21. /**
  22. * @brief Enable access to CSR_CYCLE and CSR_MCYCLEH
  23. * @note This Function can be called in Machine mode only
  24. *
  25. */
  26. static inline void hpm_csr_enable_access_to_csr_cycle(void)
  27. {
  28. uint32_t mcounter_en = read_csr(CSR_MCOUNTEREN);
  29. write_csr(CSR_MCOUNTEREN, mcounter_en | CSR_MCOUNTEREN_CY_MASK);
  30. }
  31. /**
  32. * @brief Disable access to CSR_CYCLE and CSR_MCYCLEH
  33. * @note This Function can be called in Machine mode only
  34. *
  35. */
  36. static inline void hpm_csr_disable_access_to_csr_cycle(void)
  37. {
  38. uint32_t mcounter_en = read_csr(CSR_MCOUNTEREN);
  39. write_csr(CSR_MCOUNTEREN, mcounter_en & ~CSR_MCOUNTEREN_CY_MASK);
  40. }
  41. /**
  42. * @brief Get the core cycle value
  43. * @note The CY bit in MCOUNTEREN must be enabled before using this API whendevice is :
  44. * - in supervisor mode if the device supports M/S/U mode, or
  45. * - in user mode if the device supports M/U mode
  46. *
  47. * @return CSR cycle value in 64-bit
  48. */
  49. static inline uint64_t hpm_csr_get_core_cycle(void)
  50. {
  51. uint64_t result;
  52. uint32_t resultl_first = read_csr(CSR_CYCLE);
  53. uint32_t resulth = read_csr(CSR_CYCLEH);
  54. uint32_t resultl_second = read_csr(CSR_CYCLE);
  55. if (resultl_first < resultl_second) {
  56. result = ((uint64_t)resulth << 32) | resultl_first; /* if CYCLE didn't roll over, return the value directly */
  57. } else {
  58. resulth = read_csr(CSR_CYCLEH);
  59. result = ((uint64_t)resulth << 32) | resultl_second; /* if CYCLE rolled over, need to get the CYCLEH again */
  60. }
  61. return result;
  62. }
  63. /**
  64. * @brief Get the core mcycle value
  65. * @note This function can be called in machine mode only
  66. *
  67. * @return CSR mcycle value in 64-bit
  68. */
  69. static inline uint64_t hpm_csr_get_core_mcycle(void)
  70. {
  71. uint64_t result;
  72. uint32_t resultl_first = read_csr(CSR_MCYCLE);
  73. uint32_t resulth = read_csr(CSR_MCYCLEH);
  74. uint32_t resultl_second = read_csr(CSR_MCYCLE);
  75. if (resultl_first < resultl_second) {
  76. result = ((uint64_t)resulth << 32) | resultl_first; /* if MCYCLE didn't roll over, return the value directly */
  77. } else {
  78. resulth = read_csr(CSR_MCYCLEH);
  79. result = ((uint64_t)resulth << 32) | resultl_second; /* if MCYCLE rolled over, need to get the MCYCLEH again */
  80. }
  81. return result;
  82. }
  83. #ifdef __cplusplus
  84. }
  85. #endif
  86. /**
  87. * @}
  88. */
  89. #endif /* HPM_CSR_DRV_H */