context_gcc.S 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * File : context_gcc.S
  3. * Change Logs:
  4. * Date Author Notes
  5. * 2010-05-17 swkyer first version
  6. */
  7. #include "../common/mips.inc"
  8. #include "../common/stackframe.h"
  9. #include "jz47xx.h"
  10. .section ".text", "ax"
  11. .set noreorder
  12. /*
  13. * rt_base_t rt_hw_interrupt_disable()
  14. */
  15. .globl rt_hw_interrupt_disable
  16. rt_hw_interrupt_disable:
  17. mfc0 v0, CP0_STATUS
  18. and v1, v0, 0xfffffffe
  19. mtc0 v1, CP0_STATUS
  20. jr ra
  21. nop
  22. /*
  23. * void rt_hw_interrupt_enable(rt_base_t level)
  24. */
  25. .globl rt_hw_interrupt_enable
  26. rt_hw_interrupt_enable:
  27. mtc0 a0, CP0_STATUS
  28. jr ra
  29. nop
  30. /*
  31. * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
  32. * a0 --> from
  33. * a1 --> to
  34. */
  35. .globl rt_hw_context_switch
  36. rt_hw_context_switch:
  37. mtc0 ra, CP0_EPC
  38. SAVE_ALL
  39. sw sp, 0(a0) /* store sp in preempted tasks TCB */
  40. lw sp, 0(a1) /* get new task stack pointer */
  41. RESTORE_ALL_AND_RET
  42. /*
  43. * void rt_hw_context_switch_to(rt_uint32 to)/*
  44. * a0 --> to
  45. */
  46. .globl rt_hw_context_switch_to
  47. rt_hw_context_switch_to:
  48. lw sp, 0(a0) /* get new task stack pointer */
  49. RESTORE_ALL_AND_RET
  50. /*
  51. * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
  52. */
  53. .globl rt_thread_switch_interrput_flag
  54. .globl rt_interrupt_from_thread
  55. .globl rt_interrupt_to_thread
  56. .globl rt_hw_context_switch_interrupt
  57. rt_hw_context_switch_interrupt:
  58. la t0, rt_thread_switch_interrput_flag
  59. lw t1, 0(t0)
  60. nop
  61. bnez t1, _reswitch
  62. nop
  63. li t1, 0x01 /* set rt_thread_switch_interrput_flag to 1 */
  64. sw t1, 0(t0)
  65. la t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
  66. sw a0, 0(t0)
  67. _reswitch:
  68. la t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */
  69. sw a1, 0(t0)
  70. jr ra
  71. nop
  72. /*
  73. * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
  74. */
  75. .globl rt_interrupt_enter
  76. .globl rt_interrupt_leave
  77. .globl mips_irq_handle
  78. mips_irq_handle:
  79. SAVE_ALL
  80. mfc0 t0, CP0_CAUSE
  81. mfc0 t1, CP0_STATUS
  82. and t0, t1
  83. andi t0, 0xff00
  84. beqz t0, spurious_interrupt
  85. nop
  86. /* switch to kernel stack */
  87. move k0, sp
  88. li sp, SYSTEM_STACK
  89. addiu sp, sp, -4
  90. sw k0, 0(sp)
  91. 1:
  92. jal rt_interrupt_enter
  93. nop
  94. jal rt_interrupt_dispatch
  95. nop
  96. jal rt_interrupt_leave
  97. nop
  98. /* switch sp back to thread's context */
  99. lw k0, 0(sp)
  100. nop
  101. move sp, k0
  102. /*
  103. * if rt_thread_switch_interrput_flag set, jump to
  104. * rt_hw_context_switch_interrupt_do and don't return
  105. */
  106. la k0, rt_thread_switch_interrput_flag
  107. lw k1, 0(k0)
  108. beqz k1, spurious_interrupt
  109. nop
  110. /*
  111. * switch to the new thread
  112. */
  113. sw zero, 0(k0) /* clear flag */
  114. la k0, rt_interrupt_from_thread
  115. lw k1, 0(k0)
  116. nop
  117. sw sp, 0(k1) /* store sp in preempted tasks's TCB */
  118. la k0, rt_interrupt_to_thread
  119. lw k1, 0(k0)
  120. nop
  121. lw sp, 0(k1) /* get new task's stack pointer */
  122. j spurious_interrupt
  123. nop
  124. spurious_interrupt:
  125. RESTORE_ALL_AND_RET
  126. .set reorder