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