1/* 2 * Copyright (c) 2006-2021, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2010-11-13 weety first version 9 */ 10 11#define CONFIG_STACKSIZE 512 12#define S_FRAME_SIZE 68 13 14#define S_PC 64 15#define S_LR 60 16#define S_SP 56 17#define S_IP 52 18#define S_FP 48 19#define S_R10 44 20#define S_R9 40 21#define S_R8 36 22#define S_R7 32 23#define S_R6 28 24#define S_R5 24 25#define S_R4 20 26#define S_R3 16 27#define S_R2 12 28#define S_R1 8 29#define S_R0 4 30#define S_CPSR 0 31 32.equ I_BIT, 0x80 @ when I bit is set, IRQ is disabled 33.equ F_BIT, 0x40 @ when F bit is set, FIQ is disabled 34 35.equ USERMODE, 0x10 36.equ FIQMODE, 0x11 37.equ IRQMODE, 0x12 38.equ SVCMODE, 0x13 39.equ ABORTMODE, 0x17 40.equ UNDEFMODE, 0x1b 41.equ MODEMASK, 0x1f 42.equ NOINT, 0xc0 43 44.equ RAM_BASE, 0x00000000 /*Start address of RAM */ 45.equ ROM_BASE, 0x80000000 /*Start address of Flash */ 46 47 48.equ EINT_ENABLE0, 0x01c48018 49.equ EINT_ENABLE1, 0x01c4801c 50 51/* 52 ************************************************************************* 53 * 54 * Jump vector table 55 * 56 ************************************************************************* 57 */ 58 59.section .init, "ax" 60.code 32 61 62.globl _start 63_start: 64 b reset 65 ldr pc, _vector_undef 66 ldr pc, _vector_swi 67 ldr pc, _vector_pabt 68 ldr pc, _vector_dabt 69 ldr pc, _vector_resv 70 ldr pc, _vector_irq 71 ldr pc, _vector_fiq 72 73_vector_undef: .word vector_undef 74_vector_swi: .word vector_swi 75_vector_pabt: .word vector_pabt 76_vector_dabt: .word vector_dabt 77_vector_resv: .word vector_resv 78_vector_irq: .word vector_irq 79_vector_fiq: .word vector_fiq 80 81.balignl 16,0xdeadbeef 82 83/* 84 ************************************************************************* 85 * 86 * Startup Code (reset vector) 87 * relocate armboot to ram 88 * setup stack 89 * jump to second stage 90 * 91 ************************************************************************* 92 */ 93 94_TEXT_BASE: 95 .word TEXT_BASE 96 97/* 98 * rtthread kernel start and end 99 * which are defined in linker script 100 */ 101.globl _rtthread_start 102_rtthread_start: 103 .word _start 104 105.globl _rtthread_end 106_rtthread_end: 107 .word _end 108 109/* 110 * rtthread bss start and end which are defined in linker script 111 */ 112.globl _bss_start 113_bss_start: 114 .word __bss_start 115 116.globl _bss_end 117_bss_end: 118 .word __bss_end 119 120/* IRQ stack memory (calculated at run-time) */ 121.globl IRQ_STACK_START 122IRQ_STACK_START: 123 .word _irq_stack_start + 1024 124 125.globl FIQ_STACK_START 126FIQ_STACK_START: 127 .word _fiq_stack_start + 1024 128 129.globl UNDEFINED_STACK_START 130UNDEFINED_STACK_START: 131 .word _undefined_stack_start + CONFIG_STACKSIZE 132 133.globl ABORT_STACK_START 134ABORT_STACK_START: 135 .word _abort_stack_start + CONFIG_STACKSIZE 136 137.globl _STACK_START 138_STACK_START: 139 .word _svc_stack_start + 1024 140 141/* ----------------------------------entry------------------------------*/ 142reset: 143 144 /* set the cpu to SVC32 mode */ 145 mrs r0,cpsr 146 bic r0,r0,#MODEMASK 147 orr r0,r0,#SVCMODE 148 msr cpsr,r0 149 150 /* mask all IRQs by clearing all bits in the INTMRs */ 151 mov r1, $0 152 ldr r0, =EINT_ENABLE0 153 str r1, [r0] 154 ldr r0, =EINT_ENABLE1 155 str r1, [r0] 156#if 0 157 /* set interrupt vector */ 158 ldr r0, _TEXT_BASE 159 mov r1, #0x00 160 add r2, r0, #0x40 /* size, 32bytes */ 161 162copy_loop: 163 ldmia r0!, {r3-r10} /* copy from source address [r0] */ 164 stmia r1!, {r3-r10} /* copy to target address [r1] */ 165 cmp r0, r2 /* until source end addreee [r2] */ 166 ble copy_loop 167#endif 168 169 /* setup stack */ 170 bl stack_setup 171 172 /* clear .bss */ 173 mov r0,#0 /* get a zero */ 174 ldr r1,=__bss_start /* bss start */ 175 ldr r2,=__bss_end /* bss end */ 176 177bss_loop: 178 cmp r1,r2 /* check if data to clear */ 179 strlo r0,[r1],#4 /* clear 4 bytes */ 180 blo bss_loop /* loop until done */ 181 182 /* call C++ constructors of global objects */ 183 ldr r0, =__ctors_start__ 184 ldr r1, =__ctors_end__ 185 186ctor_loop: 187 cmp r0, r1 188 beq ctor_end 189 ldr r2, [r0], #4 190 stmfd sp!, {r0-r1} 191 mov lr, pc 192 bx r2 193 ldmfd sp!, {r0-r1} 194 b ctor_loop 195 196ctor_end: 197 198 /* start RT-Thread Kernel */ 199 ldr pc, _rtthread_startup 200 201_rtthread_startup: 202 .word rtthread_startup 203#if defined (__FLASH_BUILD__) 204_load_address: 205 .word ROM_BASE + _TEXT_BASE 206#else 207_load_address: 208 .word RAM_BASE + _TEXT_BASE 209#endif 210 211 212/* 213 ************************************************************************* 214 * 215 * Interrupt handling 216 * 217 ************************************************************************* 218 */ 219 220.macro push_exp_reg 221 sub sp, sp, #S_FRAME_SIZE @/* Sizeof(struct rt_hw_stack) */ 222 stmib sp, {r0 - r12} @/* Calling r0-r12 */ 223 mov r0, sp 224 mrs r6, spsr @/* Save CPSR */ 225 str lr, [r0, #S_PC] @/* Push PC */ 226 str r6, [r0, #S_CPSR] @/* Push CPSR */ 227 @ switch to SVC mode with no interrupt 228 msr cpsr_c, #I_BIT|F_BIT|SVCMODE 229 str sp, [r0, #S_SP] @/* Save calling SP */ 230 str lr, [r0, #S_LR] @/* Save calling PC */ 231.endm 232/* exception handlers */ 233 .align 5 234vector_undef: 235 push_exp_reg 236 bl rt_hw_trap_udef 237 238 .align 5 239vector_swi: 240 push_exp_reg 241 bl rt_hw_trap_swi 242 243 .align 5 244vector_pabt: 245 push_exp_reg 246 bl rt_hw_trap_pabt 247 248 .align 5 249vector_dabt: 250 push_exp_reg 251 bl rt_hw_trap_dabt 252 253 .align 5 254vector_resv: 255 push_exp_reg 256 bl rt_hw_trap_resv 257 258.globl rt_interrupt_enter 259.globl rt_interrupt_leave 260.globl rt_thread_switch_interrupt_flag 261.globl rt_interrupt_from_thread 262.globl rt_interrupt_to_thread 263vector_irq: 264 stmfd sp!, {r0-r12,lr} 265 266 bl rt_interrupt_enter 267 bl rt_hw_trap_irq 268 bl rt_interrupt_leave 269 270 271 @ if rt_thread_switch_interrupt_flag set, jump to 272 @ rt_hw_context_switch_interrupt_do and don't return 273 ldr r0, =rt_thread_switch_interrupt_flag 274 ldr r1, [r0] 275 cmp r1, #1 276 beq rt_hw_context_switch_interrupt_do 277 278 ldmfd sp!, {r0-r12,lr} 279 subs pc, lr, #4 280 281 .align 5 282vector_fiq: 283 stmfd sp!,{r0-r7,lr} 284 bl rt_hw_trap_fiq 285 ldmfd sp!,{r0-r7,lr} 286 subs pc,lr,#4 287 288rt_hw_context_switch_interrupt_do: 289 mov r1, #0 @ clear flag 290 str r1, [r0] 291 292 ldmfd sp!, {r0-r12,lr}@ reload saved registers 293 stmfd sp, {r0-r2} @ save r0-r2 294 295 mrs r0, spsr @ get cpsr of interrupt thread 296 297 sub r1, sp, #4*3 298 sub r2, lr, #4 @ save old task's pc to r2 299 300 @ switch to SVC mode with no interrupt 301 msr cpsr_c, #I_BIT|F_BIT|SVCMODE 302 303 stmfd sp!, {r2} @ push old task's pc 304 stmfd sp!, {r3-r12,lr}@ push old task's lr,r12-r4 305 ldmfd r1, {r1-r3} @ restore r0-r2 of the interrupt thread 306 stmfd sp!, {r1-r3} @ push old task's r0-r2 307 stmfd sp!, {r0} @ push old task's cpsr 308 309 ldr r4, =rt_interrupt_from_thread 310 ldr r5, [r4] 311 str sp, [r5] @ store sp in preempted tasks's TCB 312 313 ldr r6, =rt_interrupt_to_thread 314 ldr r6, [r6] 315 ldr sp, [r6] @ get new task's stack pointer 316 317 ldmfd sp!, {r4} @ pop new task's cpsr to spsr 318 msr spsr_cxsf, r4 319 320 ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr 321 322 323stack_setup: 324 mrs r0, cpsr 325 bic r0, r0, #MODEMASK 326 orr r1, r0, #UNDEFMODE|NOINT 327 msr cpsr_cxsf, r1 /* undef mode */ 328 ldr sp, UNDEFINED_STACK_START 329 330 orr r1,r0,#ABORTMODE|NOINT 331 msr cpsr_cxsf,r1 /* abort mode */ 332 ldr sp, ABORT_STACK_START 333 334 orr r1,r0,#IRQMODE|NOINT 335 msr cpsr_cxsf,r1 /* IRQ mode */ 336 ldr sp, IRQ_STACK_START 337 338 orr r1,r0,#FIQMODE|NOINT 339 msr cpsr_cxsf,r1 /* FIQ mode */ 340 ldr sp, FIQ_STACK_START 341 342 bic r0,r0,#MODEMASK 343 orr r1,r0,#SVCMODE|NOINT 344 msr cpsr_cxsf,r1 /* SVC mode */ 345 346 ldr sp, _STACK_START 347 348 /* USER mode is not initialized. */ 349 bx lr /* The LR register may be not valid for the mode changes.*/ 350 351/*/*}*/ 352 353 354