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