startup_gcc.S 7.1 KB

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