winmacro.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. * Added to U-boot,
  3. * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
  4. * Copyright (C) 2007
  5. *
  6. * LEON2/3 LIBIO low-level routines
  7. * Written by Jiri Gaisler.
  8. * Copyright (C) 2004 Gaisler Research AB
  9. *
  10. * SPDX-License-Identifier: GPL-2.0+
  11. */
  12. #ifndef __SPARC_WINMACRO_H__
  13. #define __SPARC_WINMACRO_H__
  14. #include <asm/asmmacro.h>
  15. #include <asm/stack.h>
  16. /* Store the register window onto the 8-byte aligned area starting
  17. * at %reg. It might be %sp, it might not, we don't care.
  18. */
  19. #define RW_STORE(reg) \
  20. std %l0, [%reg + RW_L0]; \
  21. std %l2, [%reg + RW_L2]; \
  22. std %l4, [%reg + RW_L4]; \
  23. std %l6, [%reg + RW_L6]; \
  24. std %i0, [%reg + RW_I0]; \
  25. std %i2, [%reg + RW_I2]; \
  26. std %i4, [%reg + RW_I4]; \
  27. std %i6, [%reg + RW_I6];
  28. /* Load a register window from the area beginning at %reg. */
  29. #define RW_LOAD(reg) \
  30. ldd [%reg + RW_L0], %l0; \
  31. ldd [%reg + RW_L2], %l2; \
  32. ldd [%reg + RW_L4], %l4; \
  33. ldd [%reg + RW_L6], %l6; \
  34. ldd [%reg + RW_I0], %i0; \
  35. ldd [%reg + RW_I2], %i2; \
  36. ldd [%reg + RW_I4], %i4; \
  37. ldd [%reg + RW_I6], %i6;
  38. /* Loading and storing struct pt_reg trap frames. */
  39. #define PT_LOAD_INS(base_reg) \
  40. ldd [%base_reg + SF_REGS_SZ + PT_I0], %i0; \
  41. ldd [%base_reg + SF_REGS_SZ + PT_I2], %i2; \
  42. ldd [%base_reg + SF_REGS_SZ + PT_I4], %i4; \
  43. ldd [%base_reg + SF_REGS_SZ + PT_I6], %i6;
  44. #define PT_LOAD_GLOBALS(base_reg) \
  45. ld [%base_reg + SF_REGS_SZ + PT_G1], %g1; \
  46. ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; \
  47. ldd [%base_reg + SF_REGS_SZ + PT_G4], %g4; \
  48. ldd [%base_reg + SF_REGS_SZ + PT_G6], %g6;
  49. #define PT_LOAD_YREG(base_reg, scratch) \
  50. ld [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \
  51. wr %scratch, 0x0, %y;
  52. #define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
  53. ld [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \
  54. ld [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \
  55. ld [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc;
  56. #define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
  57. PT_LOAD_YREG(base_reg, scratch) \
  58. PT_LOAD_INS(base_reg) \
  59. PT_LOAD_GLOBALS(base_reg) \
  60. PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc)
  61. #define PT_STORE_INS(base_reg) \
  62. std %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \
  63. std %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \
  64. std %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \
  65. std %i6, [%base_reg + SF_REGS_SZ + PT_I6];
  66. #define PT_STORE_GLOBALS(base_reg) \
  67. st %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \
  68. std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \
  69. std %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \
  70. std %g6, [%base_reg + SF_REGS_SZ + PT_G6];
  71. #define PT_STORE_YREG(base_reg, scratch) \
  72. rd %y, %scratch; \
  73. st %scratch, [%base_reg + SF_REGS_SZ + PT_Y];
  74. #define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
  75. st %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \
  76. st %pt_pc, [%base_reg + SF_REGS_SZ + PT_PC]; \
  77. st %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC];
  78. #define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
  79. PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \
  80. PT_STORE_GLOBALS(base_reg) \
  81. PT_STORE_YREG(base_reg, g_scratch) \
  82. PT_STORE_INS(base_reg)
  83. /* Store the fpu register window*/
  84. #define FW_STORE(reg) \
  85. std %f0, [reg + FW_F0]; \
  86. std %f2, [reg + FW_F2]; \
  87. std %f4, [reg + FW_F4]; \
  88. std %f6, [reg + FW_F6]; \
  89. std %f8, [reg + FW_F8]; \
  90. std %f10, [reg + FW_F10]; \
  91. std %f12, [reg + FW_F12]; \
  92. std %f14, [reg + FW_F14]; \
  93. std %f16, [reg + FW_F16]; \
  94. std %f18, [reg + FW_F18]; \
  95. std %f20, [reg + FW_F20]; \
  96. std %f22, [reg + FW_F22]; \
  97. std %f24, [reg + FW_F24]; \
  98. std %f26, [reg + FW_F26]; \
  99. std %f28, [reg + FW_F28]; \
  100. std %f30, [reg + FW_F30]; \
  101. st %fsr, [reg + FW_FSR];
  102. /* Load a fpu register window from the area beginning at reg. */
  103. #define FW_LOAD(reg) \
  104. ldd [reg + FW_F0], %f0; \
  105. ldd [reg + FW_F2], %f2; \
  106. ldd [reg + FW_F4], %f4; \
  107. ldd [reg + FW_F6], %f6; \
  108. ldd [reg + FW_F8], %f8; \
  109. ldd [reg + FW_F10], %f10; \
  110. ldd [reg + FW_F12], %f12; \
  111. ldd [reg + FW_F14], %f14; \
  112. ldd [reg + FW_F16], %f16; \
  113. ldd [reg + FW_F18], %f18; \
  114. ldd [reg + FW_F20], %f20; \
  115. ldd [reg + FW_F22], %f22; \
  116. ldd [reg + FW_F24], %f24; \
  117. ldd [reg + FW_F26], %f26; \
  118. ldd [reg + FW_F28], %f28; \
  119. ldd [reg + FW_F30], %f30; \
  120. ld [reg + FW_FSR], %fsr;
  121. #endif
  122. #ifndef __SPARC_WINMACRO_H__
  123. #define __SPARC_WINMACRO_H__
  124. #include <asm/asmmacro.h>
  125. #include <asm/stack.h>
  126. /* Store the register window onto the 8-byte aligned area starting
  127. * at %reg. It might be %sp, it might not, we don't care.
  128. */
  129. #define RW_STORE(reg) \
  130. std %l0, [%reg + RW_L0]; \
  131. std %l2, [%reg + RW_L2]; \
  132. std %l4, [%reg + RW_L4]; \
  133. std %l6, [%reg + RW_L6]; \
  134. std %i0, [%reg + RW_I0]; \
  135. std %i2, [%reg + RW_I2]; \
  136. std %i4, [%reg + RW_I4]; \
  137. std %i6, [%reg + RW_I6];
  138. /* Load a register window from the area beginning at %reg. */
  139. #define RW_LOAD(reg) \
  140. ldd [%reg + RW_L0], %l0; \
  141. ldd [%reg + RW_L2], %l2; \
  142. ldd [%reg + RW_L4], %l4; \
  143. ldd [%reg + RW_L6], %l6; \
  144. ldd [%reg + RW_I0], %i0; \
  145. ldd [%reg + RW_I2], %i2; \
  146. ldd [%reg + RW_I4], %i4; \
  147. ldd [%reg + RW_I6], %i6;
  148. /* Loading and storing struct pt_reg trap frames. */
  149. #define PT_LOAD_INS(base_reg) \
  150. ldd [%base_reg + SF_REGS_SZ + PT_I0], %i0; \
  151. ldd [%base_reg + SF_REGS_SZ + PT_I2], %i2; \
  152. ldd [%base_reg + SF_REGS_SZ + PT_I4], %i4; \
  153. ldd [%base_reg + SF_REGS_SZ + PT_I6], %i6;
  154. #define PT_LOAD_GLOBALS(base_reg) \
  155. ld [%base_reg + SF_REGS_SZ + PT_G1], %g1; \
  156. ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; \
  157. ldd [%base_reg + SF_REGS_SZ + PT_G4], %g4; \
  158. ldd [%base_reg + SF_REGS_SZ + PT_G6], %g6;
  159. #define PT_LOAD_YREG(base_reg, scratch) \
  160. ld [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \
  161. wr %scratch, 0x0, %y;
  162. #define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
  163. ld [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \
  164. ld [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \
  165. ld [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc;
  166. #define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
  167. PT_LOAD_YREG(base_reg, scratch) \
  168. PT_LOAD_INS(base_reg) \
  169. PT_LOAD_GLOBALS(base_reg) \
  170. PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc)
  171. #define PT_STORE_INS(base_reg) \
  172. std %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \
  173. std %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \
  174. std %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \
  175. std %i6, [%base_reg + SF_REGS_SZ + PT_I6];
  176. #define PT_STORE_GLOBALS(base_reg) \
  177. st %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \
  178. std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \
  179. std %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \
  180. std %g6, [%base_reg + SF_REGS_SZ + PT_G6];
  181. #define PT_STORE_YREG(base_reg, scratch) \
  182. rd %y, %scratch; \
  183. st %scratch, [%base_reg + SF_REGS_SZ + PT_Y];
  184. #define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
  185. st %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \
  186. st %pt_pc, [%base_reg + SF_REGS_SZ + PT_PC]; \
  187. st %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC];
  188. #define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
  189. PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \
  190. PT_STORE_GLOBALS(base_reg) \
  191. PT_STORE_YREG(base_reg, g_scratch) \
  192. PT_STORE_INS(base_reg)
  193. /* Store the fpu register window*/
  194. #define FW_STORE(reg) \
  195. std %f0, [reg + FW_F0]; \
  196. std %f2, [reg + FW_F2]; \
  197. std %f4, [reg + FW_F4]; \
  198. std %f6, [reg + FW_F6]; \
  199. std %f8, [reg + FW_F8]; \
  200. std %f10, [reg + FW_F10]; \
  201. std %f12, [reg + FW_F12]; \
  202. std %f14, [reg + FW_F14]; \
  203. std %f16, [reg + FW_F16]; \
  204. std %f18, [reg + FW_F18]; \
  205. std %f20, [reg + FW_F20]; \
  206. std %f22, [reg + FW_F22]; \
  207. std %f24, [reg + FW_F24]; \
  208. std %f26, [reg + FW_F26]; \
  209. std %f28, [reg + FW_F28]; \
  210. std %f30, [reg + FW_F30]; \
  211. st %fsr, [reg + FW_FSR];
  212. /* Load a fpu register window from the area beginning at reg. */
  213. #define FW_LOAD(reg) \
  214. ldd [reg + FW_F0], %f0; \
  215. ldd [reg + FW_F2], %f2; \
  216. ldd [reg + FW_F4], %f4; \
  217. ldd [reg + FW_F6], %f6; \
  218. ldd [reg + FW_F8], %f8; \
  219. ldd [reg + FW_F10], %f10; \
  220. ldd [reg + FW_F12], %f12; \
  221. ldd [reg + FW_F14], %f14; \
  222. ldd [reg + FW_F16], %f16; \
  223. ldd [reg + FW_F18], %f18; \
  224. ldd [reg + FW_F20], %f20; \
  225. ldd [reg + FW_F22], %f22; \
  226. ldd [reg + FW_F24], %f24; \
  227. ldd [reg + FW_F26], %f26; \
  228. ldd [reg + FW_F28], %f28; \
  229. ldd [reg + FW_F30], %f30; \
  230. ld [reg + FW_FSR], %fsr;
  231. #endif