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 */
|