Add 'volatile' qualifier to new CSR accessors

Through their use of the MMPTR() macro, the "classic"
csr_[read|write]simple() accsessors identify the MMIO
subregister with the 'volatile' qualifier.

Adjust the new, csr_[rd|wr]_uint[8|16|32|64]() accessors
to also utilize the 'volatile' qualifier. Since accesses
are implicit (a[i], where a is an 'unsigned long *'),
change 'a' to be a 'volatile unsigned long *' instead.

No difference was noticed in opcodes generated using the
gcc9 risc-v cross-compiler on x86_64 with standard LiteX
cflags (vexriscv and rocket were tested), but since
reports exist that 'volatile' matters on some combinations
of compilers and targets, add the 'volatile' qualifier just
to be on the safe side.

Signed-off-by: Gabriel Somlo <gsomlo@gmail.com
This commit is contained in:
Gabriel Somlo 2020-02-06 18:30:22 -05:00
parent 485934edc9
commit 173117ad4b
1 changed files with 12 additions and 12 deletions

View File

@ -70,7 +70,7 @@ static inline int num_subregs(int csr_bytes)
} }
/* Read a CSR of size 'csr_bytes' located at address 'a'. */ /* Read a CSR of size 'csr_bytes' located at address 'a'. */
static inline uint64_t _csr_rd(unsigned long *a, int csr_bytes) static inline uint64_t _csr_rd(volatile unsigned long *a, int csr_bytes)
{ {
uint64_t r = a[0]; uint64_t r = a[0];
for (int i = 1; i < num_subregs(csr_bytes); i++) { for (int i = 1; i < num_subregs(csr_bytes); i++) {
@ -81,7 +81,7 @@ static inline uint64_t _csr_rd(unsigned long *a, int csr_bytes)
} }
/* Write value 'v' to a CSR of size 'csr_bytes' located at address 'a'. */ /* Write value 'v' to a CSR of size 'csr_bytes' located at address 'a'. */
static inline void _csr_wr(unsigned long *a, uint64_t v, int csr_bytes) static inline void _csr_wr(volatile unsigned long *a, uint64_t v, int csr_bytes)
{ {
int ns = num_subregs(csr_bytes); int ns = num_subregs(csr_bytes);
for (int i = 0; i < ns; i++) for (int i = 0; i < ns; i++)
@ -92,42 +92,42 @@ static inline void _csr_wr(unsigned long *a, uint64_t v, int csr_bytes)
static inline uint8_t csr_rd_uint8(unsigned long a) static inline uint8_t csr_rd_uint8(unsigned long a)
{ {
return _csr_rd((unsigned long *)a, sizeof(uint8_t)); return _csr_rd((volatile unsigned long *)a, sizeof(uint8_t));
} }
static inline void csr_wr_uint8(uint8_t v, unsigned long a) static inline void csr_wr_uint8(uint8_t v, unsigned long a)
{ {
_csr_wr((unsigned long *)a, v, sizeof(uint8_t)); _csr_wr((volatile unsigned long *)a, v, sizeof(uint8_t));
} }
static inline uint16_t csr_rd_uint16(unsigned long a) static inline uint16_t csr_rd_uint16(unsigned long a)
{ {
return _csr_rd((unsigned long *)a, sizeof(uint16_t)); return _csr_rd((volatile unsigned long *)a, sizeof(uint16_t));
} }
static inline void csr_wr_uint16(uint16_t v, unsigned long a) static inline void csr_wr_uint16(uint16_t v, unsigned long a)
{ {
_csr_wr((unsigned long *)a, v, sizeof(uint16_t)); _csr_wr((volatile unsigned long *)a, v, sizeof(uint16_t));
} }
static inline uint32_t csr_rd_uint32(unsigned long a) static inline uint32_t csr_rd_uint32(unsigned long a)
{ {
return _csr_rd((unsigned long *)a, sizeof(uint32_t)); return _csr_rd((volatile unsigned long *)a, sizeof(uint32_t));
} }
static inline void csr_wr_uint32(uint32_t v, unsigned long a) static inline void csr_wr_uint32(uint32_t v, unsigned long a)
{ {
_csr_wr((unsigned long *)a, v, sizeof(uint32_t)); _csr_wr((volatile unsigned long *)a, v, sizeof(uint32_t));
} }
static inline uint64_t csr_rd_uint64(unsigned long a) static inline uint64_t csr_rd_uint64(unsigned long a)
{ {
return _csr_rd((unsigned long *)a, sizeof(uint64_t)); return _csr_rd((volatile unsigned long *)a, sizeof(uint64_t));
} }
static inline void csr_wr_uint64(uint64_t v, unsigned long a) static inline void csr_wr_uint64(uint64_t v, unsigned long a)
{ {
_csr_wr((unsigned long *)a, v, sizeof(uint64_t)); _csr_wr((volatile unsigned long *)a, v, sizeof(uint64_t));
} }
/* Read a CSR located at address 'a' into an array 'buf' of 'cnt' elements. /* Read a CSR located at address 'a' into an array 'buf' of 'cnt' elements.
@ -145,7 +145,7 @@ static inline void csr_wr_uint64(uint64_t v, unsigned long a)
#define _csr_rd_buf(a, buf, cnt) \ #define _csr_rd_buf(a, buf, cnt) \
{ \ { \
int i, j, nsubs, n_sub_elem; \ int i, j, nsubs, n_sub_elem; \
unsigned long *addr = (unsigned long *)(a); \ volatile unsigned long *addr = (volatile unsigned long *)(a); \
uint64_t r; \ uint64_t r; \
if (sizeof(buf[0]) >= CSR_DW_BYTES) { \ if (sizeof(buf[0]) >= CSR_DW_BYTES) { \
/* one or more subregisters per element */ \ /* one or more subregisters per element */ \
@ -176,7 +176,7 @@ static inline void csr_wr_uint64(uint64_t v, unsigned long a)
#define _csr_wr_buf(a, buf, cnt) \ #define _csr_wr_buf(a, buf, cnt) \
{ \ { \
int i, j, nsubs, n_sub_elem; \ int i, j, nsubs, n_sub_elem; \
unsigned long *addr = (unsigned long *)(a); \ volatile unsigned long *addr = (volatile unsigned long *)(a); \
uint64_t v; \ uint64_t v; \
if (sizeof(buf[0]) >= CSR_DW_BYTES) { \ if (sizeof(buf[0]) >= CSR_DW_BYTES) { \
/* one or more subregisters per element */ \ /* one or more subregisters per element */ \