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