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 * 2006-08-31 Bernard first version 9 */ 10 11 /* Internal Memory Base Addresses */ 12 .equ FLASH_BASE, 0x00100000 13 .equ RAM_BASE, 0x00200000 14 15 /* Stack Configuration */ 16 .equ TOP_STACK, 0x00204000 17 .equ UND_STACK_SIZE, 0x00000100 18 .equ SVC_STACK_SIZE, 0x00000400 19 .equ ABT_STACK_SIZE, 0x00000100 20 .equ FIQ_STACK_SIZE, 0x00000100 21 .equ IRQ_STACK_SIZE, 0x00000100 22 .equ USR_STACK_SIZE, 0x00000004 23 24 /* ARM architecture definitions */ 25 .equ MODE_USR, 0x10 26 .equ MODE_FIQ, 0x11 27 .equ MODE_IRQ, 0x12 28 .equ MODE_SVC, 0x13 29 .equ MODE_ABT, 0x17 30 .equ MODE_UND, 0x1B 31 .equ MODE_SYS, 0x1F 32 33 .equ I_BIT, 0x80 /* when this bit is set, IRQ is disabled */ 34 .equ F_BIT, 0x40 /* when this bit is set, FIQ is disabled */ 35 36.section .init, "ax" 37.code 32 38.align 0 39.globl _start 40_start: 41 b reset 42 ldr pc, _vector_undef 43 ldr pc, _vector_swi 44 ldr pc, _vector_pabt 45 ldr pc, _vector_dabt 46 nop /* reserved vector */ 47 ldr pc, _vector_irq 48 ldr pc, _vector_fiq 49 50_vector_undef: .word vector_undef 51_vector_swi: .word vector_swi 52_vector_pabt: .word vector_pabt 53_vector_dabt: .word vector_dabt 54_vector_resv: .word vector_resv 55_vector_irq: .word vector_irq 56_vector_fiq: .word vector_fiq 57 58/* 59 * rtthread bss start and end 60 * which are defined in linker script 61 */ 62.globl _bss_start 63_bss_start: .word __bss_start 64.globl _bss_end 65_bss_end: .word __bss_end 66 67/* the system entry */ 68reset: 69 /* disable watchdog */ 70 ldr r0, =0xFFFFFD40 71 ldr r1, =0x00008000 72 str r1, [r0, #0x04] 73 74 /* enable the main oscillator */ 75 ldr r0, =0xFFFFFC00 76 ldr r1, =0x00000601 77 str r1, [r0, #0x20] 78 79 /* wait for main oscillator to stabilize */ 80moscs_loop: 81 ldr r2, [r0, #0x68] 82 ands r2, r2, #1 83 beq moscs_loop 84 85 /* set up the PLL */ 86 ldr r1, =0x00191C05 87 str r1, [r0, #0x2C] 88 89 /* wait for PLL to lock */ 90pll_loop: 91 ldr r2, [r0, #0x68] 92 ands r2, r2, #0x04 93 beq pll_loop 94 95 /* select clock */ 96 ldr r1, =0x00000007 97 str r1, [r0, #0x30] 98 99#ifdef __FLASH_BUILD__ 100 /* copy exception vectors into internal sram */ 101 /* 102 mov r8, #RAM_BASE 103 ldr r9, =_start 104 ldmia r9!, {r0-r7} 105 stmia r8!, {r0-r7} 106 ldmia r9!, {r0-r6} 107 stmia r8!, {r0-r6} 108 */ 109#endif 110 111 /* setup stack for each mode */ 112 ldr r0, =TOP_STACK 113 114 /* set stack */ 115 /* undefined instruction mode */ 116 msr cpsr_c, #MODE_UND|I_BIT|F_BIT 117 mov sp, r0 118 sub r0, r0, #UND_STACK_SIZE 119 120 /* abort mode */ 121 msr cpsr_c, #MODE_ABT|I_BIT|F_BIT 122 mov sp, r0 123 sub r0, r0, #ABT_STACK_SIZE 124 125 /* FIQ mode */ 126 msr cpsr_c, #MODE_FIQ|I_BIT|F_BIT 127 mov sp, r0 128 sub r0, r0, #FIQ_STACK_SIZE 129 130 /* IRQ mode */ 131 msr cpsr_c, #MODE_IRQ|I_BIT|F_BIT 132 mov sp, r0 133 sub r0, r0, #IRQ_STACK_SIZE 134 135 /* supervisor mode */ 136 msr cpsr_c, #MODE_SVC|I_BIT|F_BIT 137 mov sp, r0 138 139 /* remap SRAM to 0x0000 */ 140 /* 141 ldr r0, =0xFFFFFF00 142 mov r1, #0x01 143 str r1, [r0] 144 */ 145 146 /* mask all IRQs */ 147 ldr r1, =0xFFFFF124 148 ldr r0, =0XFFFFFFFF 149 str r0, [r1] 150 151 /* copy .data to SRAM */ 152 ldr r1, =_sidata /* .data start in image */ 153 ldr r2, =_edata /* .data end in image */ 154 ldr r3, =_sdata /* sram data start */ 155data_loop: 156 ldr r0, [r1, #0] 157 str r0, [r3] 158 159 add r1, r1, #4 160 add r3, r3, #4 161 162 cmp r3, r2 /* check if data to clear */ 163 blo data_loop /* loop until done */ 164 165 /* clear .bss */ 166 mov r0,#0 /* get a zero */ 167 ldr r1,=__bss_start /* bss start */ 168 ldr r2,=__bss_end /* bss end */ 169 170bss_loop: 171 cmp r1,r2 /* check if data to clear */ 172 strlo r0,[r1],#4 /* clear 4 bytes */ 173 blo bss_loop /* loop until done */ 174 175 /* call C++ constructors of global objects */ 176 ldr r0, =__ctors_start__ 177 ldr r1, =__ctors_end__ 178 179ctor_loop: 180 cmp r0, r1 181 beq ctor_end 182 ldr r2, [r0], #4 183 stmfd sp!, {r0-r1} 184 mov lr, pc 185 bx r2 186 ldmfd sp!, {r0-r1} 187 b ctor_loop 188ctor_end: 189 190 191 /* start RT-Thread Kernel */ 192 ldr pc, _rtthread_startup 193 194_rtthread_startup: .word rtthread_startup 195 196/* exception handlers */ 197vector_undef: b vector_undef 198vector_swi : b vector_swi 199vector_pabt : b vector_pabt 200vector_dabt : b vector_dabt 201vector_resv : b vector_resv 202 203.globl rt_interrupt_enter 204.globl rt_interrupt_leave 205.globl rt_thread_switch_interrupt_flag 206.globl rt_interrupt_from_thread 207.globl rt_interrupt_to_thread 208vector_irq: 209 stmfd sp!, {r0-r12,lr} 210 bl rt_interrupt_enter 211 bl rt_hw_trap_irq 212 bl rt_interrupt_leave 213 214 /* 215 * if rt_thread_switch_interrupt_flag set, jump to 216 * rt_hw_context_switch_interrupt_do and don't return 217 */ 218 ldr r0, =rt_thread_switch_interrupt_flag 219 ldr r1, [r0] 220 cmp r1, #1 221 beq rt_hw_context_switch_interrupt_do 222 223 ldmfd sp!, {r0-r12,lr} 224 subs pc, lr, #4 225 226vector_fiq: 227 stmfd sp!,{r0-r7,lr} 228 bl rt_hw_trap_fiq 229 ldmfd sp!,{r0-r7,lr} 230 subs pc,lr,#4 231 232/* 233 * void rt_hw_context_switch_interrupt_do(rt_base_t flag) 234 */ 235rt_hw_context_switch_interrupt_do: 236 mov r1, #0 @ clear flag 237 str r1, [r0] 238 239 ldmfd sp!, {r0-r12,lr}@ reload saved registers 240 stmfd sp!, {r0-r3} @ save r0-r3 241 mov r1, sp 242 add sp, sp, #16 @ restore sp 243 sub r2, lr, #4 @ save old task's pc to r2 244 245 mrs r3, spsr @ disable interrupt 246 orr r0, r3, #I_BIT|F_BIT 247 msr spsr_c, r0 248 249 ldr r0, =.+8 @ switch to interrupted task's stack 250 movs pc, r0 251 252 stmfd sp!, {r2} @ push old task's pc 253 stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 254 mov r4, r1 @ Special optimised code below 255 mov r5, r3 256 ldmfd r4!, {r0-r3} 257 stmfd sp!, {r0-r3} @ push old task's r3-r0 258 stmfd sp!, {r5} @ push old task's psr 259 mrs r4, spsr 260 stmfd sp!, {r4} @ push old task's spsr 261 262 ldr r4, =rt_interrupt_from_thread 263 ldr r5, [r4] 264 str sp, [r5] @ store sp in preempted tasks's TCB 265 266 ldr r6, =rt_interrupt_to_thread 267 ldr r6, [r6] 268 ldr sp, [r6] @ get new task's stack pointer 269 270 ldmfd sp!, {r4} @ pop new task's spsr 271 msr SPSR_cxsf, r4 272 ldmfd sp!, {r4} @ pop new task's psr 273 msr CPSR_cxsf, r4 274 275 ldmfd sp!, {r0-r12,lr,pc} @ pop new task's r0-r12,lr & pc 276