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-09-06 XuXinming first version 9 * 2006-09-20 Bernard clean the code 10 */ 11 12/** 13 * @addtogroup S3C44B0 14 */ 15/*@{*/ 16 17.section .init, "ax" 18.code 32 19.globl _start 20_start: 21 b reset 22 ldr pc, _vector_undef 23 ldr pc, _vector_swi 24 ldr pc, _vector_pabt 25 ldr pc, _vector_dabt 26 ldr pc, _vector_resv 27 ldr pc, _vector_irq 28 ldr pc, _vector_fiq 29 30_vector_undef: .word vector_undef 31_vector_swi: .word vector_swi 32_vector_pabt: .word vector_pabt 33_vector_dabt: .word vector_dabt 34_vector_resv: .word vector_resv 35_vector_irq: .word vector_irq 36_vector_fiq: .word vector_fiq 37 38.text 39.code 32 40 41/* 42 * rtthread kernel start and end 43 * which are defined in linker script 44 */ 45.globl _rtthread_start 46_rtthread_start:.word _start 47.globl _rtthread_end 48_rtthread_end: .word _end 49 50/* 51 * rtthread bss start and end 52 * which are defined in linker script 53 */ 54.globl _bss_start 55_bss_start: .word __bss_start 56.globl _bss_end 57_bss_end: .word __bss_end 58 59#if defined(__FLASH_BUILD__) 60/* 61 * TEXT_BASE, 62 * which is defined in macro of make 63 */ 64_TEXT_BASE: .word TEXT_BASE 65#endif 66 67 .equ WTCON, 0x1d30000 68 .equ INTCON, 0x1e00000 69 .equ INTMSK, 0x1e0000c 70 71/* the system entry */ 72reset: 73 /* enter svc mode */ 74 msr cpsr_c, #SVCMODE|NOINT 75 76 /*watch dog disable */ 77 ldr r0,=WTCON 78 ldr r1,=0x0 79 str r1,[r0] 80 81 /* all interrupt disable */ 82 ldr r0,=INTMSK 83 ldr r1,=0x07ffffff 84 str r1,[r0] 85 86 ldr r1, =INTCON 87 ldr r0, =0x05 88 str r0, [r1] 89 90#if defined(__FLASH_BUILD__) 91 /* init lowlevel */ 92 bl lowlevel_init 93#endif 94 95 /* setup stack */ 96 bl stack_setup 97 98#if defined(__FLASH_BUILD__) 99 mov r0, #0x0 /* r0 <- flash base address */ 100 ldr r1, _TEXT_BASE /* r1 <- the taget address */ 101 102 ldr r2, _rtthread_start 103 ldr r3, _bss_start 104 sub r2, r3, r2 /* r2 <- size of rtthread kernel */ 105 add r2, r0, r2 /* r2 <- source end address */ 106 107copy_loop: 108 ldmia r0!, {r3-r10} /* copy from source address [r0] */ 109 stmia r1!, {r3-r10} /* copy to target address [r1] */ 110 cmp r0, r2 /* until source end addreee [r2] */ 111 ble copy_loop 112#endif 113 114 /* start RT-Thread Kernel */ 115 ldr pc, _rtthread_startup 116 117_rtthread_startup: .word rtthread_startup 118 119 .equ USERMODE, 0x10 120 .equ FIQMODE, 0x11 121 .equ IRQMODE, 0x12 122 .equ SVCMODE, 0x13 123 .equ ABORTMODE, 0x17 124 .equ UNDEFMODE, 0x1b 125 .equ MODEMASK, 0x1f 126 .equ NOINT, 0xc0 127 128/* exception handlers */ 129vector_undef: bl rt_hw_trap_udef 130vector_swi: bl rt_hw_trap_swi 131vector_pabt: bl rt_hw_trap_pabt 132vector_dabt: bl rt_hw_trap_dabt 133vector_resv: bl rt_hw_trap_resv 134 135.globl rt_interrupt_enter 136.globl rt_interrupt_leave 137.globl rt_thread_switch_interrupt_flag 138.globl rt_interrupt_from_thread 139.globl rt_interrupt_to_thread 140vector_irq: 141 stmfd sp!, {r0-r12,lr} 142 bl led_off 143 bl rt_interrupt_enter 144 bl rt_hw_trap_irq 145 bl rt_interrupt_leave 146 147 /* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */ 148 ldr r0, =rt_thread_switch_interrupt_flag 149 ldr r1, [r0] 150 cmp r1, #1 151 beq _interrupt_thread_switch 152 153 ldmfd sp!, {r0-r12,lr} 154 subs pc, lr, #4 155 156 .align 5 157vector_fiq: 158 stmfd sp!,{r0-r7,lr} 159 bl rt_hw_trap_fiq 160 ldmfd sp!,{r0-r7,lr} 161 subs pc,lr,#4 162 163_interrupt_thread_switch: 164 mov r1, #0 @ clear rt_thread_switch_interrupt_flag 165 str r1, [r0] 166 167 ldmfd sp!, {r0-r12,lr} @ reload saved registers 168 stmfd sp!, {r0-r3} @ save r0-r3 169 mov r1, sp 170 add sp, sp, #16 @ restore sp 171 sub r2, lr, #4 @ save old task's pc to r2 172 173 mrs r3, spsr @ disable interrupt 174 orr r0, r3, #NOINT 175 msr spsr_c, r0 176 177 ldr r0, =.+8 @ switch to interrupted task's stack 178 movs pc, r0 179 180 stmfd sp!, {r2} @ push old task's pc 181 stmfd sp!, {r4-r12,lr} @ push old task's lr,r12-r4 182 mov r4, r1 @ Special optimised code below 183 mov r5, r3 184 ldmfd r4!, {r0-r3} 185 stmfd sp!, {r0-r3} @ push old task's r3-r0 186 stmfd sp!, {r5} @ push old task's psr 187 mrs r4, spsr 188 stmfd sp!, {r4} @ push old task's spsr 189 190 ldr r4, =rt_interrupt_from_thread 191 ldr r5, [r4] 192 str sp, [r5] @ store sp in preempted tasks's TCB 193 194 ldr r6, =rt_interrupt_to_thread 195 ldr r6, [r6] 196 ldr sp, [r6] @ get new task's stack pointer 197 198 ldmfd sp!, {r4} @ pop new task's spsr 199 msr SPSR_cxsf, r4 200 ldmfd sp!, {r4} @ pop new task's psr 201 msr CPSR_cxsf, r4 202 203 ldmfd sp!, {r0-r12,lr,pc} @ pop new task's r0-r12,lr & pc 204 205/* each mode stack memory */ 206UNDSTACK_START: .word _undefined_stack_start + 128 207ABTSTACK_START: .word _abort_stack_start + 128 208FIQSTACK_START: .word _fiq_stack_start + 1024 209IRQSTACK_START: .word _irq_stack_start + 1024 210SVCSTACK_START: .word _svc_stack_start + 4096 211 212stack_setup: 213 /* undefined instruction mode */ 214 msr cpsr_c, #UNDEFMODE|NOINT 215 ldr sp, UNDSTACK_START 216 217 /* abort mode */ 218 msr cpsr_c, #ABORTMODE|NOINT 219 ldr sp, ABTSTACK_START 220 221 /* FIQ mode */ 222 msr cpsr_c, #FIQMODE|NOINT 223 ldr sp, FIQSTACK_START 224 225 /* IRQ mode */ 226 msr cpsr_c, #IRQMODE|NOINT 227 ldr sp, IRQSTACK_START 228 229 /* supervisor mode */ 230 msr cpsr_c, #SVCMODE|NOINT 231 ldr sp, SVCSTACK_START 232 233 mov pc,lr @ The LR register may be not valid for the mode changes. 234 235.globl led_on 236led_on: 237 ldr r1, =0x1d20014 @ r1<-PDATC 238 ldr r0, [r1] @ r0<-[r1] 239 orr r0, r0, #0x0e @ r0=r0 or 0x0e 240 str r0, [r1] @ r0->[r1] 241 mov pc, lr 242 243.globl led_off 244led_off: 245 ldr r1, =0x1d20010 @ r1<-PCONC 246 ldr r0, =0x5f555555 @ r0<-0x5f555555 247 str r0, [r1] @ r0->[r1] 248 249 ldr r1, =0x1d20014 @ r1<-PDATC 250 ldr r0, =0x0 @ r0<-00 251 str r0, [r1] @ r0->[r1] 252 253 mov pc, lr 254