• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)31 static 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)42 static 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)56 static 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)77 static 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