aboutsummaryrefslogtreecommitdiffstats
path: root/src/arch/riscv/include/ipxe/csr.h
blob: c149744728632666457da31ee113c800eec1be9d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#ifndef _IPXE_CSR_H
#define _IPXE_CSR_H

/** @file
 *
 * Control and status registers (CSRs)
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

/**
 * Check if CSR can be read
 *
 * @v name		CSR name
 * @v allowed		CSR can be read
 */
#define csr_can_read( name ) ( {					\
	unsigned long stvec_orig;					\
	unsigned long stvec_temp;					\
	unsigned long csr;						\
	int allowed = 0;						\
									\
	__asm__ __volatile__ ( /* Set temporary trap vector */		\
			       "la %3, 1f\n\t"				\
			       "csrrw %2, stvec, %3\n\t"		\
			       /* Try reading CSR */			\
			       "csrr %1, " name "\n\t"			\
			       /* Mark as allowed if not trapped */	\
			       "addi %0, %0, 1\n\t"			\
			       /* Temporary trap vector */		\
			       ".balign 4\n\t"				\
			       "\n1:\n\t"				\
			       /* Restore original trap vector */	\
			       "csrw stvec, %2\n\t"			\
			       : "+r" ( allowed ),			\
				 "=r" ( csr ),				\
				 "=r" ( stvec_orig ),			\
				 "=r" ( stvec_temp ) );			\
	allowed;							\
	} )

/**
 * Check if CSR can be written
 *
 * @v name		CSR name
 * @v value		Value to write
 * @v allowed		CSR can be written
 */
#define csr_can_write( name, value ) ( {				\
	unsigned long stvec_orig;					\
	unsigned long stvec_temp;					\
	unsigned long csr = (value);					\
	int allowed = 0;						\
									\
	__asm__ __volatile__ ( /* Set temporary trap vector */		\
			       "la %3, 1f\n\t"				\
			       "csrrw %2, stvec, %3\n\t"		\
			       /* Try writing CSR */			\
			       "csrrw %1, " name ", %1\n\t"		\
			       /* Mark as allowed if not trapped */	\
			       "addi %0, %0, 1\n\t"			\
			       /* Temporary trap vector */		\
			       ".balign 4\n\t"				\
			       "\n1:\n\t"				\
			       /* Restore original trap vector */	\
			       "csrw stvec, %2\n\t"			\
			       : "+r" ( allowed ),			\
				 "+r" ( csr ),				\
				 "=r" ( stvec_orig ),			\
				 "=r" ( stvec_temp ) );			\
	allowed;							\
	} )

#endif /* _IPXE_CSR_H */