context_gcc.S 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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. .section ".text", "ax"
  22. .set noreorder
  23. /*
  24. * rt_base_t rt_hw_interrupt_disable()
  25. */
  26. .globl rt_hw_interrupt_disable
  27. rt_hw_interrupt_disable:
  28. mfc0 v0, CP0_STATUS
  29. and v1, v0, 0xfffffffe
  30. mtc0 v1, CP0_STATUS
  31. jr ra
  32. nop
  33. /*
  34. * void rt_hw_interrupt_enable(rt_base_t level)
  35. */
  36. .globl rt_hw_interrupt_enable
  37. rt_hw_interrupt_enable:
  38. mtc0 a0, CP0_STATUS
  39. jr ra
  40. nop
  41. /*
  42. * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
  43. * a0 --> from
  44. * a1 --> to
  45. */
  46. .globl rt_hw_context_switch
  47. rt_hw_context_switch:
  48. mtc0 ra, CP0_EPC
  49. SAVE_ALL
  50. sw sp, 0(a0) /* store sp in preempted tasks TCB */
  51. lw sp, 0(a1) /* get new task stack pointer */
  52. RESTORE_ALL_AND_RET
  53. /*
  54. * void rt_hw_context_switch_to(rt_uint32 to)/*
  55. * a0 --> to
  56. */
  57. .globl rt_hw_context_switch_to
  58. rt_hw_context_switch_to:
  59. lw sp, 0(a0) /* get new task stack pointer */
  60. RESTORE_ALL_AND_RET
  61. /*
  62. * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
  63. */
  64. .globl rt_thread_switch_interrupt_flag
  65. .globl rt_interrupt_from_thread
  66. .globl rt_interrupt_to_thread
  67. .globl rt_hw_context_switch_interrupt
  68. rt_hw_context_switch_interrupt:
  69. la t0, rt_thread_switch_interrupt_flag
  70. lw t1, 0(t0)
  71. nop
  72. bnez t1, _reswitch
  73. nop
  74. li t1, 0x01 /* set rt_thread_switch_interrupt_flag to 1 */
  75. sw t1, 0(t0)
  76. la t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
  77. sw a0, 0(t0)
  78. _reswitch:
  79. la t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */
  80. sw a1, 0(t0)
  81. jr ra
  82. nop
  83. /*
  84. * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
  85. */
  86. .globl rt_interrupt_enter
  87. .globl rt_interrupt_leave
  88. .globl mips_irq_handle
  89. mips_irq_handle:
  90. SAVE_ALL
  91. mfc0 t0, CP0_CAUSE
  92. and t1, t0, 0xff
  93. bnez t1, spurious_interrupt /* check exception */
  94. nop
  95. /* let k0 keep the current context sp */
  96. move k0, sp
  97. /* switch to kernel stack */
  98. li sp, SYSTEM_STACK
  99. jal rt_interrupt_enter
  100. nop
  101. jal rt_interrupt_dispatch
  102. nop
  103. jal rt_interrupt_leave
  104. nop
  105. /* switch sp back to thread's context */
  106. move sp, k0
  107. /*
  108. * if rt_thread_switch_interrupt_flag set, jump to
  109. * rt_hw_context_switch_interrupt_do and don't return
  110. */
  111. la k0, rt_thread_switch_interrupt_flag
  112. lw k1, 0(k0)
  113. beqz k1, spurious_interrupt
  114. nop
  115. sw zero, 0(k0) /* clear flag */
  116. nop
  117. /*
  118. * switch to the new thread
  119. */
  120. la k0, rt_interrupt_from_thread
  121. lw k1, 0(k0)
  122. nop
  123. sw sp, 0(k1) /* store sp in preempted tasks's TCB */
  124. la k0, rt_interrupt_to_thread
  125. lw k1, 0(k0)
  126. nop
  127. lw sp, 0(k1) /* get new task's stack pointer */
  128. j spurious_interrupt
  129. nop
  130. spurious_interrupt:
  131. RESTORE_ALL_AND_RET
  132. .set reorder