Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef __HW_COMMON_H
- #define __HW_COMMON_H
- #include <stdint.h>
- /* To overwrite CSR accessors, define extern, non-inlined versions
- * of csr_read[bwl]() and csr_write[bwl](), and define
- * CSR_ACCESSORS_DEFINED.
- */
- #ifndef CSR_ACCESSORS_DEFINED
- #define CSR_ACCESSORS_DEFINED
- #ifdef __ASSEMBLER__
- #define MMPTR(x) x
- #else /* ! __ASSEMBLER__ */
- /* CSRs are stored in subregister slices of CONFIG_CSR_DATA_WIDTH (native
- * endianness), with the least significant slice at the lowest aligned
- * (base) address. */
- #include <generated/soc.h>
- #if !defined(CONFIG_CSR_ALIGNMENT) || !defined(CONFIG_CSR_DATA_WIDTH)
- #error csr alignment and data-width MUST be set before including this file!
- #endif
- #if CONFIG_CSR_DATA_WIDTH > CONFIG_CSR_ALIGNMENT
- #error invalid CONFIG_CSR_DATA_WIDTH (must not exceed CONFIG_CSR_ALIGNMENT)!
- #endif
- #define CSR_ADDR_INC sizeof(unsigned long) // a.k.a. CONFIG_CSR_ALIGNMENT/8
- /* FIXME: preprocessor can't evaluate 'sizeof()' operator !!!
- #if CSR_ADDR_INC != CONFIG_CSR_ALIGNMENT/8
- #error invalid CONFIG_CSR_ALIGNMENT (must match native CPU word size)!
- #endif
- */
- /* CSR subregisters are embedded inside native CPU word aligned locations: */
- #define MMPTR(a) (*((volatile unsigned long *)(a)))
- /* Number of subregs required for various int types, given subreg. width:
- * +-----+------------+
- * | csr | sizeof(v) |
- * | _dw | 1 2 4 8 |
- * | |------------|
- * | 1 | 1 2 4 8 |
- * | 2 | 1 1 2 4 |
- * | 4 | 1 1 1 2 |
- * | 8 | 1 1 1 1 |
- * +-----+------------+ */
- #define _CSR_N_SUBS(v) ((sizeof(v) - 1) / (CONFIG_CSR_DATA_WIDTH / 8) + 1)
- #define _CSR_REG_WR(v, a) \
- { \
- int n_subs = _CSR_N_SUBS(v); \
- for (int i = 0; i < n_subs; i++) \
- MMPTR((a) + CSR_ADDR_INC * i) = \
- v >> (CONFIG_CSR_DATA_WIDTH * (n_subs - 1 - i)); \
- }
- #define _CSR_REG_RD(r, a) \
- { \
- int n_subs = _CSR_N_SUBS(r); \
- r = 0; \
- for (int i = 0; i < n_subs; i++) \
- r |= MMPTR((a) + CSR_ADDR_INC * i) << \
- (CONFIG_CSR_DATA_WIDTH * (n_subs - 1 - i)); \
- }
- static inline void csr_wr_uint8(uint8_t v, unsigned long a)
- {
- _CSR_REG_WR(v, a);
- }
- static inline void csr_wr_uint16(uint16_t v, unsigned long a)
- {
- _CSR_REG_WR(v, a);
- }
- static inline void csr_wr_uint32(uint32_t v, unsigned long a)
- {
- _CSR_REG_WR(v, a);
- }
- static inline void csr_wr_uint64(uint64_t v, unsigned long a)
- {
- _CSR_REG_WR(v, a);
- }
- static inline uint8_t csr_rd_uint8(unsigned long a)
- {
- uint8_t r;
- _CSR_REG_RD(r, a);
- return r;
- }
- static inline uint16_t csr_rd_uint16(unsigned long a)
- {
- uint16_t r;
- _CSR_REG_RD(r, a);
- return r;
- }
- static inline uint32_t csr_rd_uint32(unsigned long a)
- {
- uint32_t r;
- _CSR_REG_RD(r, a);
- return r;
- }
- static inline uint64_t csr_rd_uint64(unsigned long a)
- {
- uint64_t r;
- _CSR_REG_RD(r, a);
- return r;
- }
- #endif /* ! __ASSEMBLER__ */
- #endif /* ! CSR_ACCESSORS_DEFINED */
- #endif /* __HW_COMMON_H */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement