startup_gcc.S 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  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. * 2016-09-07 Urey first version
  9. */
  10. #ifndef __ASSEMBLY__
  11. #define __ASSEMBLY__
  12. #endif
  13. #include "../common/mips.h"
  14. #define IRQ_STACK_SIZE 0x2000
  15. #define EXC_STACK_SIZE 0x2000
  16. .section ".bss"
  17. ALIGN(4)
  18. irq_stack_low:
  19. .space IRQ_STACK_SIZE
  20. irq_stack_top:
  21. .space 8
  22. ALIGN(4)
  23. exc_stack_low:
  24. .space EXC_STACK_SIZE
  25. exc_stack_top:
  26. .space 8
  27. #define SYSTEM_STACK 0x80003fe8
  28. ;/*********************************************************************************************************
  29. ; Èë¿Ú
  30. ;*********************************************************************************************************/
  31. .global rtthread_startup
  32. .global mips_vfp32_init
  33. .global _start
  34. .section ".start", "ax"
  35. .set noreorder
  36. _start:
  37. .set noreorder
  38. la ra, _start
  39. li t1, 0x00800000
  40. mtc0 t1, CP0_CAUSE
  41. /* init cp0 registers. */
  42. li t0, 0x1000FC00 /* BEV = 0 and mask all interrupt */
  43. mtc0 t0, CP0_STATUS
  44. #ifdef __mips_hard_float
  45. jal mips_vfp32_init
  46. nop
  47. #endif
  48. /* setup stack pointer */
  49. li sp, SYSTEM_STACK
  50. la gp, _gp
  51. _cache_init:
  52. /* init caches, assumes a 4way * 128set * 32byte I/D cache */
  53. mtc0 zero, CP0_TAGLO /* TAGLO reg */
  54. mtc0 zero, CP0_TAGHI /* TAGHI reg */
  55. li t0, 3 /* enable cache for kseg0 accesses */
  56. mtc0 t0, CP0_CONFIG /* CONFIG reg */
  57. la t0, 0x80000000 /* an idx op should use an unmappable address */
  58. ori t1, t0, 0x4000 /* 16kB cache */
  59. _cache_loop:
  60. cache 0x8, 0(t0) /* index store icache tag */
  61. cache 0x9, 0(t0) /* index store dcache tag */
  62. bne t0, t1, _cache_loop
  63. addiu t0, t0, 0x20 /* 32 bytes per cache line */
  64. nop
  65. /* invalidate BTB */
  66. mfc0 t0, CP0_CONFIG
  67. nop
  68. ori t0, 2
  69. mtc0 t0, CP0_CONFIG
  70. nop
  71. /* jump to RT-Thread RTOS */
  72. jal rtthread_startup
  73. nop
  74. /* restart, never die */
  75. j _start
  76. nop
  77. .set reorder
  78. ;/*********************************************************************************************************
  79. ; Òì³£ÏòÁ¿±í
  80. ;*********************************************************************************************************/
  81. /* 0x0 - TLB refill handler */
  82. .section .vectors.1, "ax", %progbits
  83. j mips_tlb_refill_entry
  84. nop
  85. /* 0x100 - Cache error handler */
  86. .section .vectors.2, "ax", %progbits
  87. j mips_cache_error_entry
  88. nop
  89. /* 0x180 - Exception/Interrupt handler */
  90. .section .vectors.3, "ax", %progbits
  91. j mips_exception_entry
  92. nop
  93. /* 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE) */
  94. .section .vectors.4, "ax", %progbits
  95. j mips_interrupt_entry
  96. nop
  97. .section .vectors, "ax", %progbits
  98. .global mips_exception_handler
  99. // .global mips_syscall
  100. LEAF(mips_exception_entry)
  101. .set push
  102. .set noat
  103. .set noreorder
  104. .set volatile
  105. mfc0 k0, C0_CAUSE
  106. andi k0, k0, 0x7c
  107. beq zero, k0, except_do_intr
  108. nop
  109. andi k0,(0x08 << 2)
  110. beq zero,k0,except_do
  111. nop
  112. except_do_intr:
  113. la k0,mips_interrupt_entry
  114. jr k0
  115. nop
  116. except_do_syscall:
  117. // la k0,mips_syscall
  118. // jr k0
  119. nop
  120. except_do:
  121. //save sp
  122. move k0,sp
  123. //la sp, exc_stack_top
  124. subu sp, sp, CONTEXT_SIZE
  125. //save context
  126. sw $0, (4*0)(sp);
  127. sw $1, (4*1)(sp);
  128. sw $2, (4*2)(sp);
  129. sw $3, (4*3)(sp);
  130. sw $4, (4*4)(sp);
  131. sw $5, (4*5)(sp);
  132. sw $6, (4*6)(sp);
  133. sw $7, (4*7)(sp);
  134. sw $8, (4*8)(sp);
  135. sw $9, (4*9)(sp);
  136. sw $10, (4*10)(sp);
  137. sw $11, (4*11)(sp);
  138. sw $12, (4*12)(sp);
  139. sw $13, (4*13)(sp);
  140. sw $14, (4*14)(sp);
  141. sw $15, (4*15)(sp);
  142. sw $16, (4*16)(sp);
  143. sw $17, (4*17)(sp);
  144. sw $18, (4*18)(sp);
  145. sw $19, (4*19)(sp);
  146. sw $20, (4*20)(sp);
  147. sw $21, (4*21)(sp);
  148. sw $22, (4*22)(sp);
  149. sw $23, (4*23)(sp);
  150. sw $24, (4*24)(sp);
  151. sw $25, (4*25)(sp);
  152. sw $26, (4*26)(sp);
  153. sw $27, (4*27)(sp);
  154. sw $28, (4*28)(sp);
  155. sw k0, (4*29)(sp); //old sp
  156. sw $30, (4*30)(sp);
  157. sw $31, (4*31)(sp);
  158. /* STATUS CAUSE EPC.... */
  159. mfc0 $2, CP0_STATUS
  160. sw $2, STK_OFFSET_SR(sp)
  161. mfc0 $2, CP0_CAUSE
  162. sw $2, STK_OFFSET_CAUSE(sp)
  163. mfc0 $2, CP0_BADVADDR
  164. sw $2, STK_OFFSET_BADVADDR(sp)
  165. MFC0 $2, CP0_EPC
  166. sw $2, STK_OFFSET_EPC(sp)
  167. mfhi $2
  168. sw $2, STK_OFFSET_HI(sp)
  169. mflo $2
  170. sw $2, STK_OFFSET_LO(sp)
  171. move a0, sp
  172. la k0, mips_exception_handler
  173. j k0
  174. nop
  175. //
  176. .set pop
  177. END(mips_exception_entry)
  178. .global mips_tlb_refill_handler
  179. LEAF(mips_tlb_refill_entry)
  180. .set push
  181. .set noat
  182. .set noreorder
  183. .set volatile
  184. la k0,mips_tlb_refill_handler
  185. jr k0
  186. nop
  187. eret
  188. nop
  189. .set pop
  190. END(mips_tlb_refill_entry)
  191. .global mips_cache_error_handler
  192. LEAF(mips_cache_error_entry)
  193. .set push
  194. .set noat
  195. .set noreorder
  196. .set volatile
  197. la k0,mips_cache_error_handler
  198. jr k0
  199. nop
  200. eret
  201. nop
  202. .set pop
  203. END(mips_cache_error_entry)
  204. .global rt_interrupt_dispatch
  205. .global rt_interrupt_enter
  206. .global rt_interrupt_leave
  207. LEAF(mips_interrupt_entry)
  208. .set push
  209. .set noat
  210. .set noreorder
  211. .set volatile
  212. //mfc0 k0,CP0_EPC
  213. SAVE_CONTEXT
  214. mfc0 t0, CP0_CAUSE
  215. mfc0 t1, CP0_STATUS
  216. and t0, t1
  217. andi t0, 0xff00
  218. beqz t0, spurious_interrupt
  219. nop
  220. /* let k0 keep the current context sp */
  221. move k0, sp
  222. /* switch to kernel stack */
  223. la sp, irq_stack_top
  224. jal rt_interrupt_enter
  225. nop
  226. jal rt_interrupt_dispatch
  227. nop
  228. jal rt_interrupt_leave
  229. nop
  230. /* switch sp back to thread's context */
  231. move sp, k0
  232. /*
  233. * if rt_thread_switch_interrupt_flag set, jump to
  234. * rt_hw_context_switch_interrupt_do and don't return
  235. */
  236. la k0, rt_thread_switch_interrupt_flag
  237. lw k1, 0(k0)
  238. beqz k1, spurious_interrupt
  239. nop
  240. sw zero, 0(k0) /* clear flag */
  241. nop
  242. /*
  243. * switch to the new thread
  244. */
  245. la k0, rt_interrupt_from_thread
  246. lw k1, 0(k0)
  247. nop
  248. sw sp, 0(k1) /* store sp in preempted tasks's TCB */
  249. la k0, rt_interrupt_to_thread
  250. lw k1, 0(k0)
  251. nop
  252. lw sp, 0(k1) /* get new task's stack pointer */
  253. j spurious_interrupt
  254. nop
  255. spurious_interrupt:
  256. RESTORE_CONTEXT
  257. .set pop
  258. END(mips_interrupt_entry)