context_gcc.S 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * Copyright (c) 2006-2020, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-12-04 Jiaxun Yang Initial version
  9. * 2020-07-26 lizhirui Fixed some problems
  10. */
  11. #ifndef __ASSEMBLY__
  12. #define __ASSEMBLY__
  13. #endif
  14. #include "mips_regs.h"
  15. #include "stackframe.h"
  16. .section ".text", "ax"
  17. .set noreorder
  18. /*
  19. * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
  20. * a0 --> from
  21. * a1 --> to
  22. */
  23. .globl rt_hw_context_switch
  24. rt_hw_context_switch:
  25. MTC0 ra, CP0_EPC
  26. SAVE_ALL
  27. REG_S sp, 0(a0) /* store sp in preempted tasks TCB */
  28. REG_L sp, 0(a1) /* get new task stack pointer */
  29. RESTORE_ALL_AND_RET
  30. /*
  31. * void rt_hw_context_switch_to(rt_uint32 to)/*
  32. * a0 --> to
  33. */
  34. .globl rt_hw_context_switch_to
  35. rt_hw_context_switch_to:
  36. REG_L sp, 0(a0) /* get new task stack pointer */
  37. RESTORE_ALL_AND_RET
  38. /*
  39. * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
  40. */
  41. .globl rt_thread_switch_interrupt_flag
  42. .globl rt_interrupt_from_thread
  43. .globl rt_interrupt_to_thread
  44. .globl rt_hw_context_switch_interrupt
  45. rt_hw_context_switch_interrupt:
  46. PTR_LA t0, rt_thread_switch_interrupt_flag
  47. REG_L t1, 0(t0)
  48. nop
  49. bnez t1, _reswitch
  50. nop
  51. li t1, 0x01 /* set rt_thread_switch_interrupt_flag to 1 */
  52. LONG_S t1, 0(t0)
  53. PTR_LA t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
  54. LONG_S a0, 0(t0)
  55. _reswitch:
  56. PTR_LA t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */
  57. LONG_S a1, 0(t0)
  58. jr ra
  59. nop
  60. /*
  61. * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
  62. */
  63. .globl rt_interrupt_enter
  64. .globl rt_interrupt_leave
  65. .globl rt_general_exc_dispatch
  66. .globl mips_irq_handle
  67. mips_irq_handle:
  68. SAVE_ALL
  69. /* let k0 keep the current context sp */
  70. move k0, sp
  71. /* switch to kernel stack */
  72. PTR_LA sp, _system_stack
  73. jal rt_interrupt_enter
  74. nop
  75. /* Get Old SP from k0 as paremeter in a0 */
  76. move a0, k0
  77. jal rt_general_exc_dispatch
  78. nop
  79. jal rt_interrupt_leave
  80. nop
  81. /* switch sp back to thread context */
  82. move sp, k0
  83. /*
  84. * if rt_thread_switch_interrupt_flag set, jump to
  85. * rt_hw_context_switch_interrupt_do and do not return
  86. */
  87. PTR_LA k0, rt_thread_switch_interrupt_flag
  88. LONG_L k1, 0(k0)
  89. beqz k1, spurious_interrupt
  90. nop
  91. LONG_S zero, 0(k0) /* clear flag */
  92. nop
  93. /*
  94. * switch to the new thread
  95. */
  96. PTR_LA k0, rt_interrupt_from_thread
  97. LONG_L k1, 0(k0)
  98. nop
  99. LONG_S sp, 0(k1) /* store sp in preempted task TCB */
  100. PTR_LA k0, rt_interrupt_to_thread
  101. LONG_L k1, 0(k0)
  102. nop
  103. LONG_L sp, 0(k1) /* get new task stack pointer */
  104. j spurious_interrupt
  105. nop
  106. spurious_interrupt:
  107. RESTORE_ALL_AND_RET
  108. .set reorder