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