context_gcc.S 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * File : context_gcc.S
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2010-05-17 swkyer first version
  13. * 2010-09-11 bernard port to Loongson SoC3210
  14. * 2011-08-08 lgnq port to Loongson LS1B
  15. */
  16. #ifndef __ASSEMBLY__
  17. #define __ASSEMBLY__
  18. #endif
  19. #include "../common/mips_def.h"
  20. #include "../common/stackframe.h"
  21. #include "stackframe_fpu.h"
  22. .section ".text", "ax"
  23. .set noreorder
  24. /*
  25. * rt_base_t rt_hw_interrupt_disable()
  26. */
  27. .globl rt_hw_interrupt_disable
  28. rt_hw_interrupt_disable:
  29. mfc0 v0, CP0_STATUS
  30. and v1, v0, 0xfffffffe
  31. mtc0 v1, CP0_STATUS
  32. jr ra
  33. nop
  34. /*
  35. * void rt_hw_interrupt_enable(rt_base_t level)
  36. */
  37. .globl rt_hw_interrupt_enable
  38. rt_hw_interrupt_enable:
  39. ori a0, 0x00000800
  40. mtc0 a0, CP0_STATUS
  41. ehb
  42. mfc0 v0, CP0_CAUSE
  43. ehb
  44. or v1, v0, 0x800000 //EBASE + 0x200
  45. mtc0 v1, CP0_CAUSE
  46. ehb
  47. jr ra
  48. nop
  49. /*
  50. * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
  51. * a0 --> from
  52. * a1 --> to
  53. */
  54. .globl rt_hw_context_switch
  55. rt_hw_context_switch:
  56. mtc0 ra, CP0_EPC
  57. SAVE_ALL
  58. SAVE_FPU
  59. sw sp, 0(a0) /* store sp in preempted tasks TCB */
  60. lw sp, 0(a1) /* get new task stack pointer */
  61. RESTORE_FPU
  62. RESTORE_ALL_AND_RET
  63. /*
  64. * void rt_hw_context_switch_to(rt_uint32 to)/*
  65. * a0 --> to
  66. */
  67. .globl rt_hw_context_switch_to
  68. rt_hw_context_switch_to:
  69. lw sp, 0(a0) /* get new task stack pointer */
  70. RESTORE_FPU
  71. RESTORE_ALL_AND_RET
  72. /*
  73. * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
  74. */
  75. .globl rt_thread_switch_interrupt_flag
  76. .globl rt_interrupt_from_thread
  77. .globl rt_interrupt_to_thread
  78. .globl rt_hw_context_switch_interrupt
  79. rt_hw_context_switch_interrupt:
  80. la t0, rt_thread_switch_interrupt_flag
  81. lw t1, 0(t0)
  82. nop
  83. bnez t1, _reswitch
  84. nop
  85. li t1, 0x01 /* set rt_thread_switch_interrupt_flag to 1 */
  86. sw t1, 0(t0)
  87. la t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
  88. sw a0, 0(t0)
  89. _reswitch:
  90. la t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */
  91. sw a1, 0(t0)
  92. jr ra
  93. nop
  94. /*
  95. * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
  96. */
  97. .globl rt_interrupt_enter
  98. .globl rt_interrupt_leave
  99. .globl mips_irq_handle
  100. mips_irq_handle:
  101. SAVE_ALL
  102. SAVE_FPU
  103. mfc0 t0, CP0_CAUSE
  104. and t1, t0, 0xff
  105. bnez t1, spurious_interrupt /* check exception */
  106. nop
  107. /* let k0 keep the current context sp */
  108. move k0, sp
  109. /* switch to kernel stack */
  110. li sp, SYSTEM_STACK
  111. jal rt_interrupt_enter
  112. nop
  113. jal rt_interrupt_dispatch
  114. nop
  115. jal rt_interrupt_leave
  116. nop
  117. /* switch sp back to thread's context */
  118. move sp, k0
  119. /*
  120. * if rt_thread_switch_interrupt_flag set, jump to
  121. * rt_hw_context_switch_interrupt_do and don't return
  122. */
  123. la k0, rt_thread_switch_interrupt_flag
  124. lw k1, 0(k0)
  125. beqz k1, spurious_interrupt
  126. nop
  127. sw zero, 0(k0) /* clear flag */
  128. nop
  129. /*
  130. * switch to the new thread
  131. */
  132. la k0, rt_interrupt_from_thread
  133. lw k1, 0(k0)
  134. nop
  135. sw sp, 0(k1) /* store sp in preempted tasks's TCB */
  136. la k0, rt_interrupt_to_thread
  137. lw k1, 0(k0)
  138. nop
  139. lw sp, 0(k1) /* get new task's stack pointer */
  140. j spurious_interrupt
  141. nop
  142. spurious_interrupt:
  143. RESTORE_FPU
  144. RESTORE_ALL_AND_RET
  145. .set reorder