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 /* setup stack for each mode */ 100 ldr r0, =TOP_STACK 101 102 /* set stack */ 103 /* undefined instruction mode */ 104 msr cpsr_c, #MODE_UND|I_BIT|F_BIT 105 mov sp, r0 106 sub r0, r0, #UND_STACK_SIZE 107 108 /* abort mode */ 109 msr cpsr_c, #MODE_ABT|I_BIT|F_BIT 110 mov sp, r0 111 sub r0, r0, #ABT_STACK_SIZE 112 113 /* FIQ mode */ 114 msr cpsr_c, #MODE_FIQ|I_BIT|F_BIT 115 mov sp, r0 116 sub r0, r0, #FIQ_STACK_SIZE 117 118 /* IRQ mode */ 119 msr cpsr_c, #MODE_IRQ|I_BIT|F_BIT 120 mov sp, r0 121 sub r0, r0, #IRQ_STACK_SIZE 122 123 /* supervisor mode */ 124 msr cpsr_c, #MODE_SVC 125 mov sp, r0 126 127#ifdef __FLASH_BUILD__ 128 /* Relocate .data section (Copy from ROM to RAM) */ 129 ldr r1, =_etext 130 ldr r2, =_data 131 ldr r3, =_edata 132data_loop: 133 cmp r2, r3 134 ldrlo r0, [r1], #4 135 strlo r0, [r2], #4 136 blo data_loop 137#else 138 /* remap SRAM to 0x0000 */ 139 ldr r0, =0xFFFFFF00 140 mov r1, #0x01 141 str r1, [r0] 142#endif 143 144 /* mask all IRQs */ 145 ldr r1, =0xFFFFF124 146 ldr r0, =0XFFFFFFFF 147 str r0, [r1] 148 149 /* start RT-Thread Kernel */ 150 ldr pc, _rtthread_startup 151 152_rtthread_startup: .word rtthread_startup 153 154/* exception handlers */ 155vector_undef: b vector_undef 156vector_swi : b vector_swi 157vector_pabt : b vector_pabt 158vector_dabt : b vector_dabt 159vector_resv : b vector_resv 160 161.globl rt_interrupt_enter 162.globl rt_interrupt_leave 163.globl rt_thread_switch_interrupt_flag 164.globl rt_interrupt_from_thread 165.globl rt_interrupt_to_thread 166vector_irq: 167 stmfd sp!, {r0-r12,lr} 168 bl rt_interrupt_enter 169 bl rt_hw_trap_irq 170 bl rt_interrupt_leave 171 172 /* 173 * if rt_thread_switch_interrupt_flag set, jump to 174 * rt_hw_context_switch_interrupt_do and don't return 175 */ 176 ldr r0, =rt_thread_switch_interrupt_flag 177 ldr r1, [r0] 178 cmp r1, #1 179 beq rt_hw_context_switch_interrupt_do 180 181 ldmfd sp!, {r0-r12,lr} 182 subs pc, lr, #4 183 184vector_fiq: 185 stmfd sp!,{r0-r7,lr} 186 bl rt_hw_trap_fiq 187 ldmfd sp!,{r0-r7,lr} 188 subs pc,lr,#4 189 190/* 191 * void rt_hw_context_switch_interrupt_do(rt_base_t flag) 192 */ 193rt_hw_context_switch_interrupt_do: 194 mov r1, #0 /* clear flag */ 195 str r1, [r0] 196 197 ldmfd sp!, {r0-r12,lr} /* reload saved registers */ 198 stmfd sp!, {r0-r3} /* save r0-r3 */ 199 mov r1, sp 200 add sp, sp, #16 /* restore sp */ 201 sub r2, lr, #4 /* save old task's pc to r2 */ 202 203 mrs r3, spsr /* disable interrupt */ 204 orr r0, r3, #I_BIT|F_BIT 205 msr spsr_c, r0 206 207 ldr r0, =.+8 /* switch to interrupted task's stack */ 208 movs pc, r0 209 210 stmfd sp!, {r2} /* push old task's pc */ 211 stmfd sp!, {r4-r12,lr} /* push old task's lr,r12-r4 */ 212 mov r4, r1 /* Special optimised code below */ 213 mov r5, r3 214 ldmfd r4!, {r0-r3} 215 stmfd sp!, {r0-r3} /* push old task's r3-r0 */ 216 stmfd sp!, {r5} /* push old task's psr */ 217 mrs r4, spsr 218 stmfd sp!, {r4} /* push old task's spsr */ 219 220 ldr r4, =rt_interrupt_from_thread 221 ldr r5, [r4] 222 str sp, [r5] /* store sp in preempted tasks's TCB */ 223 224 ldr r6, =rt_interrupt_to_thread 225 ldr r6, [r6] 226 ldr sp, [r6] /* get new task's stack pointer */ 227 228 ldmfd sp!, {r4} /* pop new task's spsr */ 229 msr SPSR_cxsf, r4 230 ldmfd sp!, {r4} /* pop new task's psr */ 231 msr CPSR_cxsf, r4 232 233 ldmfd sp!, {r0-r12,lr,pc} /* pop new task's r0-r12,lr & pc */ 234