1/* 2 * File : start.S 3 * This file is part of RT-Thread RTOS 4 * COPYRIGHT (C) 2006 - 2013, 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 * 2013-07-13 Peng Fan First implementation 23 */ 24 25 26#define CONFIG_STACKSIZE 1024 27#define S_FRAME_SIZE 132 28 29#define S_OLD_R0 132 30#define S_PSR 128 31#define S_PC 124 32#define S_LR 120 33#define S_SP 116 34 35#define S_IP 112 36#define S_FP 108 37#define S_R26 104 38#define S_R25 100 39#define S_R24 96 40#define S_R23 92 41#define S_R22 88 42#define S_R21 84 43#define S_R20 80 44#define S_R19 76 45#define S_R18 72 46#define S_R17 68 47#define S_R16 64 48#define S_R15 60 49#define S_R14 56 50#define S_R13 52 51#define S_R12 48 52#define S_R11 44 53#define S_R10 40 54#define S_R9 36 55#define S_R8 32 56#define S_R7 28 57#define S_R6 24 58#define S_R5 20 59#define S_R4 16 60#define S_R3 12 61#define S_R2 8 62#define S_R1 4 63#define S_R0 0 64 65.equ USERMODE, 0x10 66.equ REALMODE, 0x11 67.equ IRQMODE, 0x12 68.equ PRIVMODE, 0x13 69.equ TRAPMODE, 0x17 70.equ EXTNMODE, 0x1b 71.equ MODEMASK, 0x1f 72.equ NOINT, 0xc0 73 74/* 75 ************************************************************************* 76 * 77 * Jump vector table 78 * 79 ************************************************************************* 80 */ 81 82.section .init, "ax" 83.code 32 84.globl _start 85_start: 86 b reset 87 ldw pc, _extend_handle 88 ldw pc, _swi_handle 89 ldw pc, _iabort_handle 90 ldw pc, _dabort_handle 91 ldw pc, _reserve_handle 92 ldw pc, _IRQ_handle 93 ldw pc, _FIQ_handle 94 95_extend_handle: .word extend_handle 96_swi_handle: .word swi_handle 97_iabort_handle: .word iabort_handle 98_dabort_handle: .word dabort_handle 99_reserve_handle: .word reserve_handle 100_IRQ_handle: .word IRQ_handle 101_FIQ_handle: .word FIQ_handle 102 .balignl 16,0xdeadbeef 103 104/* 105 ************************************************************************* 106 * 107 * Startup Code (reset vector) 108 * relocate armboot to ram 109 * setup stack 110 * jump to second stage 111 * 112 ************************************************************************* 113 */ 114.global _TEXT_BASE 115_TEXT_BASE: 116 .word TEXT_BASE 117 118.globl _rtthread_start 119_rtthread_start: 120 .word _start 121 122.globl _rtthread_end 123_rtthread_end: 124 .word _end 125 126.globl _bss_start 127_bss_start: 128 .word __bss_start @ load end address 129 130.globl _bss_end 131_bss_end: 132 .word __bss_end 133 134.globl IRQ_STACK_START 135IRQ_STACK_START: 136 .word _irq_stack_start + 1024 137 138.globl FIQ_STACK_START 139FIQ_STACK_START: 140 .word _fiq_stack_start +1024 141 142.globl UNDEFINED_STACK_START 143UNDEFINED_STACK_START: 144 .word _undefined_stack_start + CONFIG_STACKSIZE 145 146.globl ABORT_STACK_START 147ABORT_STACK_START: 148 .word _abort_stack_start + CONFIG_STACKSIZE 149 150.globl _STACK_START 151_STACK_START: 152 .word _priv_stack_start + 4096 153 154.equ SEP6200_VIC_BASE, 0xb0000000 155.equ SEP6200_SYSCTL_BASE, 0xb0008000 156/* ----------------------------------entry------------------------------*/ 157reset: 158 /* set the cpu to PRIV mode and disable cpu interrupt */ 159 mov r0, asr 160 andn r0, r0, #0xff 161 or r0, r0, #PRIVMODE|NOINT 162 mov.a asr, r0 163 164 /* mask all IRQs by clearing all bits in the INTMRs */ 165 ldw r1, =SEP6200_VIC_BASE 166 ldw r0, =0xffffffff 167 stw r0, [r1+], #0x20 /*interrupt enable clear*/ 168 stw r0, [r1+], #0x24 169 170 171 /*remap ddr to 0x00000000 address*/ 172 ldw r1, =SEP6200_SYSCTL_BASE 173 ldw r0, [r1+] 174 ldw r2, =0x80000000 175 or r0, r0, r2 176 stw r2, [r1+] 177 178 /* set interrupt vector */ 179 /*do nothing here for vector*/ 180 181 /* setup stack */ 182 b.l stack_setup 183 184 /* copy the vector code to address 0 */ 185 ldw r12, =0x100 186 ldw r0, = 0x40000000 187 ldw r1, = 0x00000000 188copy_vetor: 189 ldw r2, [r0] 190 stw r2, [r1] 191 add r0, r0, #4 192 add r1, r1, #4 193 sub r12, r12, #4 194 cmpsub.a r12, #0 195 bne copy_vetor 196 197 /* clear .bss */ 198 ldw r0, _bss_start /* bss start */ 199 ldw r1, _bss_end /* bss end */ 200 mov r2,#0 /* get a zero */ 201 202 203bss_loop: 204 stw r2, [r0] @ clear loop... 205 add r0, r0, #4 206 cmpsub.a r0, r1 207 bel bss_loop 208 209 /* call C++ constructors of global objects */ 210 ldw r0, =__ctors_start__ 211 ldw r1, =__ctors_end__ 212 213ctor_loop: 214 cmpsub.a r0, r1 215 beq ctor_end 216 ldw.w r2, [r0]+, #4 217 stm.w (r0, r1), [sp-] 218 add lr, pc, #4 219 mov pc, r2 220 ldm.w (r0, r1), [sp]+ 221 b ctor_loop 222ctor_end: 223 224 /*enable interrupt*/ 225 mov r0, asr 226 andn r1, r0, #NOINT 227 mov.a asr, r1 228 229 /* start RT-Thread Kernel */ 230 ldw pc, _rtthread_startup 231 232_rtthread_startup: 233 .word rtthread_startup 234 235/* 236 ************************************************************************* 237 * 238 * Interrupt handling 239 * 240 ************************************************************************* 241 */ 242 243/* exception handlers */ 244/*Just simple implementation here */ 245 .align 5 246extend_handle: 247 b rt_hw_trap_extn 248swi_handle: 249 b rt_hw_trap_swi 250iabort_handle: 251 b rt_hw_trap_pabt 252dabort_handle: 253 b rt_hw_trap_dabt 254reserve_handle: 255 b rt_hw_trap_resv 256 257.globl rt_interrupt_enter 258.globl rt_interrupt_leave 259.globl rt_thread_switch_interrupt_flag 260.globl rt_interrupt_from_thread 261.globl rt_interrupt_to_thread 262IRQ_handle: 263 264 stm.w (lr), [sp-] 265 stm.w (r16 - r28), [sp-] 266 stm.w (r0 - r15), [sp-] 267 268 b.l rt_interrupt_enter 269 b.l rt_hw_trap_irq 270 b.l rt_interrupt_leave 271 272 /* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */ 273 ldw r0, =rt_thread_switch_interrupt_flag 274 ldw r1, [r0+] 275 cmpsub.a r1, #1 276 beq _interrupt_thread_switch 277 278 ldm.w (r0 - r15), [sp]+ 279 ldm.w (r16 - r28), [sp]+ 280 ldm.w (lr), [sp]+ 281 mov.a pc, lr 282 283 .align 5 284FIQ_handle: 285 b rt_hw_trap_fiq 286 287_interrupt_thread_switch: 288 289 mov r1, #0 /* clear rt_thread_switch_interrupt_flag*/ 290 stw r1, [r0+] 291 292 /*reload register*/ 293 ldm.w (r0 - r15), [sp]+ 294 ldm.w (r16 - r28), [sp]+ 295 ldm.w (lr), [sp]+ 296 297 stm.w (r0 - r3), [sp-] /*save r0-r3*/ 298 299 mov r1, sp 300 add sp, sp, #16 /* restore sp */ 301 mov r2, lr /* save old task's pc to r2 */ 302 303 mov r3, bsr 304 mov r0, #0xd3 /*I:F:0:PRIV*/ 305 mov.a asr, r0 306 307 stm.w (r2), [sp-] /* push old task's pc */ 308 309 /* push old task's registers */ 310 stm.w (lr), [sp-] 311 stm.w (r16 - r28), [sp-] 312 stm.w (r4 - r15), [sp-] 313 mov r4, r1 /* Special optimised code below */ 314 mov r5, r3 315 ldm.w (r0 - r3), [r4]+ 316 stm.w (r0 - r3), [sp-] /*push old task's r3-r0*/ 317 stm.w (r5), [sp-] /* push old task's asr */ 318 mov r4, bsr 319 stm.w (r4), [sp-] /* push old task's bsr*/ 320 321 ldw r4, =rt_interrupt_from_thread 322 ldw r5, [r4+] 323 stw sp, [r5+] /* store sp in preempted tasks's TCB*/ 324 325 ldw r6, =rt_interrupt_to_thread 326 ldw r6, [r6+] 327 ldw sp, [r6+] /* get new task's stack pointer */ 328 329 ldm.w (r4), [sp]+ /* pop new task's spsr */ 330 mov.a bsr, r4 331 ldm.w (r4), [sp]+ /* pop new task's psr */ 332 mov.a asr, r4 333 334 /* pop new task's r0-r28,lr & pc */ 335 336 ldm.w (r0 - r15), [sp]+ 337 ldm.w (r16 - r28), [sp]+ 338 ldm.w (lr), [sp]+ 339 ldm.w (pc), [sp]+ 340 341stack_setup: 342 /*irq*/ 343 mov ip, lr 344 mov r0, asr 345 andn r0, r0, #0x1f 346 or r0, r0, #IRQMODE|NOINT 347 mov.a asr, r0 /*IRQMODE*/ 348 ldw r0, =IRQ_STACK_START 349 ldw sp, [r0+] 350 /*ldw sp, IRQ_STACK_START*/ 351 352 /*priv*/ 353 mov r0, asr 354 andn r0, r0, #0x1f 355 or r0, r0, #PRIVMODE|NOINT 356 mov.a asr, r0 /*PRIVMODE*/ 357 ldw r0, =_STACK_START 358 ldw sp, [r0+] 359 /*ldw sp, _STACK_START*/ 360 mov lr, ip 361 /*fiq and other mode is not implemented in code here*/ 362 mov pc, lr /*lr may not be valid for the mode changes*/ 363/*/*}*/ 364