/* low level macros for accessing memory mapped hardware registers */
#define REG64(addr) ((volatile uint64_t *)(uintptr_t)(addr))
#define REG32(addr) ((volatile uint32_t *)(uintptr_t)(addr))
#define REG16(addr) ((volatile uint16_t *)(uintptr_t)(addr))
#define REG8(addr) ((volatile uint8_t *)(uintptr_t)(addr))
I understand the cast to uint64_t*
but why volatile
? Which optimization is being prevented here?
Also, why cast to uintptr_t = typedef unsigned long uintptr_t
before casting to uintXX_t
?