1/* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2008-12-11 XuXinming first version 9 * 2011-03-17 Bernard update to 0.4.x 10 */ 11 12#define WDMOD (0xE0000000 + 0x00) 13#define VICIntEnClr (0xFFFFF000 + 0x014) 14#define VICVectAddr (0xFFFFF000 + 0xF00) 15#define VICIntSelect (0xFFFFF000 + 0x00C) 16#define PLLCFG (0xE01FC000 + 0x084) 17#define PLLCON (0xE01FC000 + 0x080) 18#define PLLFEED (0xE01FC000 + 0x08C) 19#define PLLSTAT (0xE01FC000 + 0x088) 20#define CCLKCFG (0xE01FC000 + 0x104) 21#define MEMMAP (0xE01FC000 + 0x040) 22#define SCS (0xE01FC000 + 0x1A0) 23#define CLKSRCSEL (0xE01FC000 + 0x10C) 24#define MAMCR (0xE01FC000 + 0x000) 25#define MAMTIM (0xE01FC000 + 0x004) 26 27/* stack memory */ 28.section .bss.noinit 29.equ IRQ_STACK_SIZE, 0x00000200 30.equ FIQ_STACK_SIZE, 0x00000100 31.equ UDF_STACK_SIZE, 0x00000004 32.equ ABT_STACK_SIZE, 0x00000004 33.equ SVC_STACK_SIZE, 0x00000200 34 35.space IRQ_STACK_SIZE 36IRQ_STACK: 37 38.space FIQ_STACK_SIZE 39FIQ_STACK: 40 41.space UDF_STACK_SIZE 42UDF_STACK: 43 44.space ABT_STACK_SIZE 45ABT_STACK: 46 47.space SVC_STACK_SIZE 48SVC_STACK: 49 50.section .init, "ax" 51.code 32 52.globl _start 53_start: 54 b reset 55 ldr pc, _vector_undef 56 ldr pc, _vector_swi 57 ldr pc, _vector_pabt 58 ldr pc, _vector_dabt 59 ldr pc, _vector_resv 60 ldr pc, _vector_irq 61 ldr pc, _vector_fiq 62 63_vector_undef: .word vector_undef 64_vector_swi: .word vector_swi 65_vector_pabt: .word vector_pabt 66_vector_dabt: .word vector_dabt 67_vector_resv: .word vector_resv 68_vector_irq: .word vector_irq 69_vector_fiq: .word vector_fiq 70 71.balignl 16,0xdeadbeef 72 73/* 74 * rtthread kernel start and end 75 * which are defined in linker script 76 */ 77.globl _rtthread_start 78_rtthread_start: 79 .word _start 80 81.globl _rtthread_end 82_rtthread_end: 83 .word _end 84 85/* 86 * rtthread bss start and end which are defined in linker script 87 */ 88.globl _bss_start 89_bss_start: 90 .word __bss_start 91 92.globl _bss_end 93_bss_end: 94 .word __bss_end 95 96.text 97.code 32 98 99/* the system entry */ 100reset: 101 /* enter svc mode */ 102 msr cpsr_c, #SVCMODE|NOINT 103 104 /*watch dog disable */ 105 ldr r0,=WDMOD 106 ldr r1,=0x0 107 str r1,[r0] 108 109 /* all interrupt disable */ 110 ldr r0,=VICIntEnClr 111 ldr r1,=0xffffffff 112 str r1,[r0] 113 114 ldr r1, =VICVectAddr 115 ldr r0, =0x00 116 str r0, [r1] 117 118 ldr r1, =VICIntSelect 119 ldr r0, =0x00 120 str r0, [r1] 121 122 /* setup stack */ 123 bl stack_setup 124 125 /* copy .data to SRAM */ 126 ldr r1, =_sidata /* .data start in image */ 127 ldr r2, =_edata /* .data end in image */ 128 ldr r3, =_sdata /* sram data start */ 129data_loop: 130 ldr r0, [r1, #0] 131 str r0, [r3] 132 133 add r1, r1, #4 134 add r3, r3, #4 135 136 cmp r3, r2 /* check if data to clear */ 137 blo data_loop /* loop until done */ 138 139 /* clear .bss */ 140 mov r0,#0 /* get a zero */ 141 ldr r1,=__bss_start /* bss start */ 142 ldr r2,=__bss_end /* bss end */ 143 144bss_loop: 145 cmp r1,r2 /* check if data to clear */ 146 strlo r0,[r1],#4 /* clear 4 bytes */ 147 blo bss_loop /* loop until done */ 148 149 /* call C++ constructors of global objects */ 150 ldr r0, =__ctors_start__ 151 ldr r1, =__ctors_end__ 152 153ctor_loop: 154 cmp r0, r1 155 beq ctor_end 156 ldr r2, [r0], #4 157 stmfd sp!, {r0-r1} 158 mov lr, pc 159 bx r2 160 ldmfd sp!, {r0-r1} 161 b ctor_loop 162ctor_end: 163 164 /* start RT-Thread Kernel */ 165 ldr pc, _rtthread_startup 166 167_rtthread_startup: 168 .word rtthread_startup 169 170 .equ USERMODE, 0x10 171 .equ FIQMODE, 0x11 172 .equ IRQMODE, 0x12 173 .equ SVCMODE, 0x13 174 .equ ABORTMODE, 0x17 175 .equ UNDEFMODE, 0x1b 176 .equ MODEMASK, 0x1f 177 .equ NOINT, 0xc0 178 179/* exception handlers */ 180vector_undef: bl rt_hw_trap_udef 181vector_swi: bl rt_hw_trap_swi 182vector_pabt: bl rt_hw_trap_pabt 183vector_dabt: bl rt_hw_trap_dabt 184vector_resv: bl rt_hw_trap_resv 185 186.globl rt_interrupt_enter 187.globl rt_interrupt_leave 188.globl rt_thread_switch_interrupt_flag 189.globl rt_interrupt_from_thread 190.globl rt_interrupt_to_thread 191vector_irq: 192 stmfd sp!, {r0-r12,lr} 193 bl rt_interrupt_enter 194 bl rt_hw_trap_irq 195 bl rt_interrupt_leave 196 197 /* if rt_thread_switch_interrupt_flag set, 198 * jump to _interrupt_thread_switch and don't return 199 */ 200 ldr r0, =rt_thread_switch_interrupt_flag 201 ldr r1, [r0] 202 cmp r1, #1 203 beq _interrupt_thread_switch 204 205 ldmfd sp!, {r0-r12,lr} 206 subs pc, lr, #4 207 208 .align 5 209vector_fiq: 210 stmfd sp!,{r0-r7,lr} 211 bl rt_hw_trap_fiq 212 ldmfd sp!,{r0-r7,lr} 213 subs pc,lr,#4 214 215_interrupt_thread_switch: 216 mov r1, #0 /* clear rt_thread_switch_interrupt_flag */ 217 str r1, [r0] 218 219 ldmfd sp!, {r0-r12,lr} /* reload saved registers */ 220 stmfd sp!, {r0-r3} /* save r0-r3 */ 221 mov r1, sp 222 add sp, sp, #16 /* restore sp */ 223 sub r2, lr, #4 /* save old task's pc to r2 */ 224 225 mrs r3, spsr /* disable interrupt */ 226 orr r0, r3, #NOINT 227 msr spsr_c, r0 228 229 ldr r0, =.+8 /* switch to interrupted task's stack */ 230 movs pc, r0 231 232 stmfd sp!, {r2} /* push old task's pc */ 233 stmfd sp!, {r4-r12,lr} /* push old task's lr,r12-r4 */ 234 mov r4, r1 /* Special optimised code below */ 235 mov r5, r3 236 ldmfd r4!, {r0-r3} 237 stmfd sp!, {r0-r3} /* push old task's r3-r0 */ 238 stmfd sp!, {r5} /* push old task's psr */ 239 mrs r4, spsr 240 stmfd sp!, {r4} /* push old task's spsr */ 241 242 ldr r4, =rt_interrupt_from_thread 243 ldr r5, [r4] 244 str sp, [r5] /* store sp in preempted tasks's TCB */ 245 246 ldr r6, =rt_interrupt_to_thread 247 ldr r6, [r6] 248 ldr sp, [r6] /* get new task's stack pointer */ 249 250 ldmfd sp!, {r4} /* pop new task's spsr */ 251 msr SPSR_cxsf, r4 252 ldmfd sp!, {r4} /* pop new task's psr */ 253 msr CPSR_cxsf, r4 254 255 ldmfd sp!, {r0-r12,lr,pc} /* pop new task's r0-r12,lr & pc */ 256 257stack_setup: 258 mrs r0, cpsr 259 bic r0, r0, #MODEMASK 260 orr r1, r0, #UNDEFMODE|NOINT 261 msr cpsr_cxsf, r1 /* undef mode */ 262 ldr sp, =UDF_STACK 263 264 orr r1,r0,#ABORTMODE|NOINT 265 msr cpsr_cxsf,r1 /* abort mode */ 266 ldr sp, =ABT_STACK 267 268 orr r1,r0,#IRQMODE|NOINT 269 msr cpsr_cxsf,r1 /* IRQ mode */ 270 ldr sp, =IRQ_STACK 271 272 orr r1,r0,#FIQMODE|NOINT 273 msr cpsr_cxsf,r1 /* FIQ mode */ 274 ldr sp, =FIQ_STACK 275 276 bic r0,r0,#MODEMASK 277 orr r1,r0,#SVCMODE|NOINT 278 msr cpsr_cxsf,r1 /* SVC mode */ 279 ldr sp, =SVC_STACK 280 281 /* USER mode is not initialized. */ 282 mov pc,lr /* The LR register may be not valid for the mode changes.*/ 283