xref: /optee_os/lib/libutee/include/riscv_user_sysreg.h (revision 53877f84472e6d29f2695bfe20d05bed577325c1)
1*53877f84SAlvin Chang /* SPDX-License-Identifier: BSD-2-Clause */
2*53877f84SAlvin Chang /*
3*53877f84SAlvin Chang  * Copyright (c) 2023 Andes Technology Corporation
4*53877f84SAlvin Chang  */
5*53877f84SAlvin Chang #ifndef RISCV_USER_SYSREG_H
6*53877f84SAlvin Chang #define RISCV_USER_SYSREG_H
7*53877f84SAlvin Chang 
8*53877f84SAlvin Chang #include <stdint.h>
9*53877f84SAlvin Chang 
10*53877f84SAlvin Chang #define read_csr(csr)							\
11*53877f84SAlvin Chang 	({								\
12*53877f84SAlvin Chang 		register unsigned long v;				\
13*53877f84SAlvin Chang 		asm volatile ("csrr %0, " #csr : "=r"(v) : : "memory");	\
14*53877f84SAlvin Chang 		v;							\
15*53877f84SAlvin Chang 	})
16*53877f84SAlvin Chang 
read_time(void)17*53877f84SAlvin Chang static inline __noprof uint64_t read_time(void)
18*53877f84SAlvin Chang {
19*53877f84SAlvin Chang 	uint64_t time = 0;
20*53877f84SAlvin Chang 	uint32_t hi __maybe_unused = 0;
21*53877f84SAlvin Chang 	uint32_t lo __maybe_unused = 0;
22*53877f84SAlvin Chang 
23*53877f84SAlvin Chang #ifdef RV32
24*53877f84SAlvin Chang 	do {
25*53877f84SAlvin Chang 		hi = read_csr(timeh);
26*53877f84SAlvin Chang 		lo = read_csr(time);
27*53877f84SAlvin Chang 	} while (hi != read_csr(timeh));
28*53877f84SAlvin Chang 
29*53877f84SAlvin Chang 	time = SHIFT_U64(hi, 32) | lo;
30*53877f84SAlvin Chang #else /*RV64*/
31*53877f84SAlvin Chang 	time = read_csr(time);
32*53877f84SAlvin Chang #endif /*RV32*/
33*53877f84SAlvin Chang 
34*53877f84SAlvin Chang 	return time;
35*53877f84SAlvin Chang }
36*53877f84SAlvin Chang 
37*53877f84SAlvin Chang /* These barriers need to enforce ordering on both devices and memory. */
mb(void)38*53877f84SAlvin Chang static inline __noprof void mb(void)
39*53877f84SAlvin Chang {
40*53877f84SAlvin Chang 	asm volatile ("fence" : : : "memory");
41*53877f84SAlvin Chang }
42*53877f84SAlvin Chang 
barrier_read_counter_timer(void)43*53877f84SAlvin Chang static inline __noprof uint64_t barrier_read_counter_timer(void)
44*53877f84SAlvin Chang {
45*53877f84SAlvin Chang 	mb();	/* Get timer value after pending operations have completed */
46*53877f84SAlvin Chang 	return read_time();
47*53877f84SAlvin Chang }
48*53877f84SAlvin Chang 
read_cntfrq(void)49*53877f84SAlvin Chang static inline __noprof uint32_t read_cntfrq(void)
50*53877f84SAlvin Chang {
51*53877f84SAlvin Chang 	return CFG_RISCV_MTIME_RATE;
52*53877f84SAlvin Chang }
53*53877f84SAlvin Chang 
54*53877f84SAlvin Chang #endif /* RISCV_USER_SYSREG_H */
55