context_gcc.S 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * Copyright (c) 2006-2019, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2010-05-17 swkyer first version
  9. * 2010-09-11 bernard port to JZ4755
  10. * 2019-07-19 Zhou Yanjie clean up code
  11. */
  12. #ifndef __ASSEMBLY__
  13. #define __ASSEMBLY__
  14. #endif
  15. #include "../common/mips_def.h"
  16. #include "../common/stackframe.h"
  17. #include "stack.h"
  18. .section ".text", "ax"
  19. .set noreorder
  20. /*
  21. * rt_base_t rt_hw_interrupt_disable()
  22. */
  23. .globl rt_hw_interrupt_disable
  24. rt_hw_interrupt_disable:
  25. mfc0 v0, CP0_STATUS
  26. and v1, v0, 0xfffffffe
  27. mtc0 v1, CP0_STATUS
  28. jr ra
  29. nop
  30. /*
  31. * void rt_hw_interrupt_enable(rt_base_t level)
  32. */
  33. .globl rt_hw_interrupt_enable
  34. rt_hw_interrupt_enable:
  35. mtc0 a0, CP0_STATUS
  36. jr ra
  37. nop
  38. /*
  39. * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
  40. * a0 --> from
  41. * a1 --> to
  42. */
  43. .globl rt_hw_context_switch
  44. rt_hw_context_switch:
  45. mtc0 ra, CP0_EPC
  46. SAVE_ALL
  47. sw sp, 0(a0) /* store sp in preempted tasks TCB */
  48. lw sp, 0(a1) /* get new task stack pointer */
  49. RESTORE_ALL_AND_RET
  50. /*
  51. * void rt_hw_context_switch_to(rt_uint32 to)/*
  52. * a0 --> to
  53. */
  54. .globl rt_hw_context_switch_to
  55. rt_hw_context_switch_to:
  56. lw sp, 0(a0) /* get new task stack pointer */
  57. RESTORE_ALL_AND_RET
  58. /*
  59. * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
  60. */
  61. .globl rt_thread_switch_interrupt_flag
  62. .globl rt_interrupt_from_thread
  63. .globl rt_interrupt_to_thread
  64. .globl rt_hw_context_switch_interrupt
  65. rt_hw_context_switch_interrupt:
  66. la t0, rt_thread_switch_interrupt_flag
  67. lw t1, 0(t0)
  68. nop
  69. bnez t1, _reswitch
  70. nop
  71. li t1, 0x01 /* set rt_thread_switch_interrupt_flag to 1 */
  72. sw t1, 0(t0)
  73. la t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
  74. sw a0, 0(t0)
  75. _reswitch:
  76. la t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */
  77. sw a1, 0(t0)
  78. jr ra
  79. nop
  80. .globl system_dump
  81. /*
  82. * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
  83. */
  84. .globl rt_interrupt_enter
  85. .globl rt_interrupt_leave
  86. .globl mips_irq_handle
  87. mips_irq_handle:
  88. SAVE_ALL
  89. mfc0 t0, CP0_CAUSE
  90. mfc0 t1, CP0_STATUS
  91. and t0, t1
  92. andi t0, 0xff00
  93. beqz t0, spurious_interrupt
  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