1
0

context_gcc.S 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2011-05-24 aozima first version
  9. * 2019-07-19 Zhou Yanjie clean up code
  10. */
  11. #ifndef __ASSEMBLY__
  12. #define __ASSEMBLY__
  13. #endif
  14. #include <p32xxxx.h>
  15. #include "../common/mips_def.h"
  16. #include "../common/stackframe.h"
  17. .section ".text", "ax"
  18. .set noat
  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 /* v0 = status */
  26. addiu v1, zero, -2 /* v1 = 0-2 = 0xFFFFFFFE */
  27. and v1, v0, v1 /* v1 = v0 & 0xFFFFFFFE */
  28. mtc0 v1, CP0_STATUS /* status = v1 */
  29. jr ra
  30. nop
  31. /*
  32. * void rt_hw_interrupt_enable(rt_base_t level)
  33. */
  34. .globl rt_hw_interrupt_enable
  35. rt_hw_interrupt_enable:
  36. mtc0 a0, CP0_STATUS
  37. jr ra
  38. nop
  39. /*
  40. * void rt_hw_context_switch_to(rt_uint32 to)/*
  41. * a0 --> to
  42. */
  43. .globl rt_hw_context_switch_to
  44. rt_hw_context_switch_to:
  45. lw sp, 0(a0) /* get new task stack pointer */
  46. RESTORE_ALL_AND_RET
  47. /*
  48. * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
  49. * a0 --> from
  50. * a1 --> to
  51. */
  52. .globl rt_hw_context_switch
  53. rt_hw_context_switch:
  54. mtc0 ra, CP0_EPC
  55. SAVE_ALL
  56. sw sp, 0(a0) /* store sp in preempted tasks TCB */
  57. lw sp, 0(a1) /* get new task stack pointer */
  58. RESTORE_ALL_AND_RET
  59. /*
  60. * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
  61. */
  62. .globl rt_thread_switch_interrupt_flag
  63. .globl rt_interrupt_from_thread
  64. .globl rt_interrupt_to_thread
  65. .globl rt_hw_context_switch_interrupt
  66. rt_hw_context_switch_interrupt:
  67. la t0, rt_thread_switch_interrupt_flag
  68. lw t1, 0(t0)
  69. nop
  70. bnez t1, _reswitch
  71. nop
  72. li t1, 0x01 /* set rt_thread_switch_interrupt_flag to 1 */
  73. sw t1, 0(t0)
  74. la t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
  75. sw a0, 0(t0)
  76. _reswitch:
  77. la t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */
  78. sw a1, 0(t0)
  79. /* trigger the soft exception (causes context switch) */
  80. mfc0 t0, CP0_CAUSE /* t0 = Cause */
  81. ori t0, t0, (1<<8) /* t0 |= (1<<8) */
  82. mtc0 t0, CP0_CAUSE /* cause = t0 */
  83. addiu t1, zero, -257 /* t1 = ~(1<<8) */
  84. and t0, t0, t1 /* t0 &= t1 */
  85. mtc0 t0, CP0_CAUSE /* cause = t0 */
  86. jr ra
  87. nop
  88. /*
  89. * void __ISR(_CORE_SOFTWARE_0_VECTOR, ipl2) CoreSW0Handler(void)
  90. */
  91. .section ".text", "ax"
  92. .set noreorder
  93. .set noat
  94. .ent CoreSW0Handler
  95. .globl CoreSW0Handler
  96. CoreSW0Handler:
  97. SAVE_ALL
  98. /* mCS0ClearIntFlag(); */
  99. la t0, IFS0CLR /* t0 = IFS0CLR */
  100. addiu t1,zero,0x02 /* t1 = (1<<2) */
  101. sw t1, 0(t0) /* IFS0CLR = t1 */
  102. la k0, rt_thread_switch_interrupt_flag
  103. sw zero, 0(k0) /* clear flag */
  104. /*
  105. * switch to the new thread
  106. */
  107. la k0, rt_interrupt_from_thread
  108. lw k1, 0(k0)
  109. nop
  110. sw sp, 0(k1) /* store sp in preempted tasks's TCB */
  111. la k0, rt_interrupt_to_thread
  112. lw k1, 0(k0)
  113. nop
  114. lw sp, 0(k1) /* get new task's stack pointer */
  115. RESTORE_ALL_AND_RET
  116. .end CoreSW0Handler