riscv_asm.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 2019 Western Digital Corporation or its affiliates.
  5. *
  6. * Authors:
  7. * Anup Patel <anup.patel@wdc.com>
  8. */
  9. #ifndef __RISCV_ASM_H__
  10. #define __RISCV_ASM_H__
  11. #include <sbi/riscv_encoding.h>
  12. /* clang-format off */
  13. #ifdef __ASSEMBLER__
  14. #define __ASM_STR(x) x
  15. #else
  16. #define __ASM_STR(x) #x
  17. #endif
  18. #if __riscv_xlen == 64
  19. #define __REG_SEL(a, b) __ASM_STR(a)
  20. #elif __riscv_xlen == 32
  21. #define __REG_SEL(a, b) __ASM_STR(b)
  22. #else
  23. #error "Unexpected __riscv_xlen"
  24. #endif
  25. #define PAGE_SHIFT (12)
  26. #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
  27. #define PAGE_MASK (~(PAGE_SIZE - 1))
  28. #define REG_L __REG_SEL(ld, lw)
  29. #define REG_S __REG_SEL(sd, sw)
  30. #define SZREG __REG_SEL(8, 4)
  31. #define LGREG __REG_SEL(3, 2)
  32. #if __SIZEOF_POINTER__ == 8
  33. #ifdef __ASSEMBLER__
  34. #define RISCV_PTR .dword
  35. #define RISCV_SZPTR 8
  36. #define RISCV_LGPTR 3
  37. #else
  38. #define RISCV_PTR ".dword"
  39. #define RISCV_SZPTR "8"
  40. #define RISCV_LGPTR "3"
  41. #endif
  42. #elif __SIZEOF_POINTER__ == 4
  43. #ifdef __ASSEMBLER__
  44. #define RISCV_PTR .word
  45. #define RISCV_SZPTR 4
  46. #define RISCV_LGPTR 2
  47. #else
  48. #define RISCV_PTR ".word"
  49. #define RISCV_SZPTR "4"
  50. #define RISCV_LGPTR "2"
  51. #endif
  52. #else
  53. #error "Unexpected __SIZEOF_POINTER__"
  54. #endif
  55. #if (__SIZEOF_INT__ == 4)
  56. #define RISCV_INT __ASM_STR(.word)
  57. #define RISCV_SZINT __ASM_STR(4)
  58. #define RISCV_LGINT __ASM_STR(2)
  59. #else
  60. #error "Unexpected __SIZEOF_INT__"
  61. #endif
  62. #if (__SIZEOF_SHORT__ == 2)
  63. #define RISCV_SHORT __ASM_STR(.half)
  64. #define RISCV_SZSHORT __ASM_STR(2)
  65. #define RISCV_LGSHORT __ASM_STR(1)
  66. #else
  67. #error "Unexpected __SIZEOF_SHORT__"
  68. #endif
  69. /* clang-format on */
  70. #ifndef __ASSEMBLER__
  71. #define csr_swap(csr, val) \
  72. ({ \
  73. unsigned long __v = (unsigned long)(val); \
  74. __asm__ __volatile__("csrrw %0, " __ASM_STR(csr) ", %1" \
  75. : "=r"(__v) \
  76. : "rK"(__v) \
  77. : "memory"); \
  78. __v; \
  79. })
  80. #define csr_read(csr) \
  81. ({ \
  82. register unsigned long __v; \
  83. __asm__ __volatile__("csrr %0, " __ASM_STR(csr) \
  84. : "=r"(__v) \
  85. : \
  86. : "memory"); \
  87. __v; \
  88. })
  89. #define csr_write(csr, val) \
  90. ({ \
  91. unsigned long __v = (unsigned long)(val); \
  92. __asm__ __volatile__("csrw " __ASM_STR(csr) ", %0" \
  93. : \
  94. : "rK"(__v) \
  95. : "memory"); \
  96. })
  97. #define csr_read_set(csr, val) \
  98. ({ \
  99. unsigned long __v = (unsigned long)(val); \
  100. __asm__ __volatile__("csrrs %0, " __ASM_STR(csr) ", %1" \
  101. : "=r"(__v) \
  102. : "rK"(__v) \
  103. : "memory"); \
  104. __v; \
  105. })
  106. #define csr_set(csr, val) \
  107. ({ \
  108. unsigned long __v = (unsigned long)(val); \
  109. __asm__ __volatile__("csrs " __ASM_STR(csr) ", %0" \
  110. : \
  111. : "rK"(__v) \
  112. : "memory"); \
  113. })
  114. #define csr_read_clear(csr, val) \
  115. ({ \
  116. unsigned long __v = (unsigned long)(val); \
  117. __asm__ __volatile__("csrrc %0, " __ASM_STR(csr) ", %1" \
  118. : "=r"(__v) \
  119. : "rK"(__v) \
  120. : "memory"); \
  121. __v; \
  122. })
  123. #define csr_clear(csr, val) \
  124. ({ \
  125. unsigned long __v = (unsigned long)(val); \
  126. __asm__ __volatile__("csrc " __ASM_STR(csr) ", %0" \
  127. : \
  128. : "rK"(__v) \
  129. : "memory"); \
  130. })
  131. unsigned long csr_read_num(int csr_num);
  132. void csr_write_num(int csr_num, unsigned long val);
  133. #define wfi() \
  134. do { \
  135. __asm__ __volatile__("wfi" ::: "memory"); \
  136. } while (0)
  137. #define ebreak() \
  138. do { \
  139. __asm__ __volatile__("ebreak" ::: "memory"); \
  140. } while (0)
  141. /* Get current HART id */
  142. #define current_hartid() ((unsigned int)csr_read(CSR_MHARTID))
  143. /* determine CPU extension, return non-zero support */
  144. int misa_extension_imp(char ext);
  145. #define misa_extension(c)\
  146. ({\
  147. _Static_assert(((c >= 'A') && (c <= 'Z')),\
  148. "The parameter of misa_extension must be [A-Z]");\
  149. misa_extension_imp(c);\
  150. })
  151. /* Get MXL field of misa, return -1 on error */
  152. int misa_xlen(void);
  153. /* Get RISC-V ISA string representation */
  154. void misa_string(int xlen, char *out, unsigned int out_sz);
  155. int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
  156. unsigned long log2len);
  157. int pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out,
  158. unsigned long *log2len);
  159. #endif /* !__ASSEMBLER__ */
  160. #endif