winmacro.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. #ifndef __SPARC_WINMACRO_H__
  22. #define __SPARC_WINMACRO_H__
  23. #include <asm/asmmacro.h>
  24. #include <asm/stack.h>
  25. /* Store the register window onto the 8-byte aligned area starting
  26. * at %reg. It might be %sp, it might not, we don't care.
  27. */
  28. #define RW_STORE(reg) \
  29. std %l0, [%reg + RW_L0]; \
  30. std %l2, [%reg + RW_L2]; \
  31. std %l4, [%reg + RW_L4]; \
  32. std %l6, [%reg + RW_L6]; \
  33. std %i0, [%reg + RW_I0]; \
  34. std %i2, [%reg + RW_I2]; \
  35. std %i4, [%reg + RW_I4]; \
  36. std %i6, [%reg + RW_I6];
  37. /* Load a register window from the area beginning at %reg. */
  38. #define RW_LOAD(reg) \
  39. ldd [%reg + RW_L0], %l0; \
  40. ldd [%reg + RW_L2], %l2; \
  41. ldd [%reg + RW_L4], %l4; \
  42. ldd [%reg + RW_L6], %l6; \
  43. ldd [%reg + RW_I0], %i0; \
  44. ldd [%reg + RW_I2], %i2; \
  45. ldd [%reg + RW_I4], %i4; \
  46. ldd [%reg + RW_I6], %i6;
  47. /* Loading and storing struct pt_reg trap frames. */
  48. #define PT_LOAD_INS(base_reg) \
  49. ldd [%base_reg + SF_REGS_SZ + PT_I0], %i0; \
  50. ldd [%base_reg + SF_REGS_SZ + PT_I2], %i2; \
  51. ldd [%base_reg + SF_REGS_SZ + PT_I4], %i4; \
  52. ldd [%base_reg + SF_REGS_SZ + PT_I6], %i6;
  53. #define PT_LOAD_GLOBALS(base_reg) \
  54. ld [%base_reg + SF_REGS_SZ + PT_G1], %g1; \
  55. ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; \
  56. ldd [%base_reg + SF_REGS_SZ + PT_G4], %g4; \
  57. ldd [%base_reg + SF_REGS_SZ + PT_G6], %g6;
  58. #define PT_LOAD_YREG(base_reg, scratch) \
  59. ld [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \
  60. wr %scratch, 0x0, %y;
  61. #define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
  62. ld [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \
  63. ld [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \
  64. ld [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc;
  65. #define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
  66. PT_LOAD_YREG(base_reg, scratch) \
  67. PT_LOAD_INS(base_reg) \
  68. PT_LOAD_GLOBALS(base_reg) \
  69. PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc)
  70. #define PT_STORE_INS(base_reg) \
  71. std %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \
  72. std %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \
  73. std %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \
  74. std %i6, [%base_reg + SF_REGS_SZ + PT_I6];
  75. #define PT_STORE_GLOBALS(base_reg) \
  76. st %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \
  77. std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \
  78. std %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \
  79. std %g6, [%base_reg + SF_REGS_SZ + PT_G6];
  80. #define PT_STORE_YREG(base_reg, scratch) \
  81. rd %y, %scratch; \
  82. st %scratch, [%base_reg + SF_REGS_SZ + PT_Y];
  83. #define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
  84. st %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \
  85. st %pt_pc, [%base_reg + SF_REGS_SZ + PT_PC]; \
  86. st %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC];
  87. #define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
  88. PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \
  89. PT_STORE_GLOBALS(base_reg) \
  90. PT_STORE_YREG(base_reg, g_scratch) \
  91. PT_STORE_INS(base_reg)
  92. /* Store the fpu register window*/
  93. #define FW_STORE(reg) \
  94. std %f0, [reg + FW_F0]; \
  95. std %f2, [reg + FW_F2]; \
  96. std %f4, [reg + FW_F4]; \
  97. std %f6, [reg + FW_F6]; \
  98. std %f8, [reg + FW_F8]; \
  99. std %f10, [reg + FW_F10]; \
  100. std %f12, [reg + FW_F12]; \
  101. std %f14, [reg + FW_F14]; \
  102. std %f16, [reg + FW_F16]; \
  103. std %f18, [reg + FW_F18]; \
  104. std %f20, [reg + FW_F20]; \
  105. std %f22, [reg + FW_F22]; \
  106. std %f24, [reg + FW_F24]; \
  107. std %f26, [reg + FW_F26]; \
  108. std %f28, [reg + FW_F28]; \
  109. std %f30, [reg + FW_F30]; \
  110. st %fsr, [reg + FW_FSR];
  111. /* Load a fpu register window from the area beginning at reg. */
  112. #define FW_LOAD(reg) \
  113. ldd [reg + FW_F0], %f0; \
  114. ldd [reg + FW_F2], %f2; \
  115. ldd [reg + FW_F4], %f4; \
  116. ldd [reg + FW_F6], %f6; \
  117. ldd [reg + FW_F8], %f8; \
  118. ldd [reg + FW_F10], %f10; \
  119. ldd [reg + FW_F12], %f12; \
  120. ldd [reg + FW_F14], %f14; \
  121. ldd [reg + FW_F16], %f16; \
  122. ldd [reg + FW_F18], %f18; \
  123. ldd [reg + FW_F20], %f20; \
  124. ldd [reg + FW_F22], %f22; \
  125. ldd [reg + FW_F24], %f24; \
  126. ldd [reg + FW_F26], %f26; \
  127. ldd [reg + FW_F28], %f28; \
  128. ldd [reg + FW_F30], %f30; \
  129. ld [reg + FW_FSR], %fsr;
  130. #endif