context_gcc.S 2.9 KB

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