diff --git a/libcpu/arm/s3c24x0/start_gcc.s b/libcpu/arm/s3c24x0/start_gcc.s new file mode 100644 index 0000000000..b975a39e38 --- /dev/null +++ b/libcpu/arm/s3c24x0/start_gcc.s @@ -0,0 +1,351 @@ +/* + * File : start.S + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2006-03-13 Bernard first version + * 2006-10-05 Alsor.Z for s3c2410 initialize + * 2008-01-29 Yi.Qiu for QEMU emulator + */ + +/** + * @addtogroup S3C2410 + */ +/*@{*/ + +#define CONFIG_STACKSIZE 512 +#define S_FRAME_SIZE 72 + +#define S_OLD_R0 68 +#define S_PSR 64 +#define S_PC 60 +#define S_LR 56 +#define S_SP 52 + +#define S_IP 48 +#define S_FP 44 +#define S_R10 40 +#define S_R9 36 +#define S_R8 32 +#define S_R7 28 +#define S_R6 24 +#define S_R5 20 +#define S_R4 16 +#define S_R3 12 +#define S_R2 8 +#define S_R1 4 +#define S_R0 0 + + .equ USERMODE, 0x10 + .equ FIQMODE, 0x11 + .equ IRQMODE, 0x12 + .equ SVCMODE, 0x13 + .equ ABORTMODE, 0x17 + .equ UNDEFMODE, 0x1b + .equ MODEMASK, 0x1f + .equ NOINT, 0xc0 + +.section .init, "ax" +.code 32 +.globl _start +_start: + b reset + ldr pc, _vector_undef + ldr pc, _vector_swi + ldr pc, _vector_pabt + ldr pc, _vector_dabt + ldr pc, _vector_resv + ldr pc, _vector_irq + ldr pc, _vector_fiq + +_vector_undef: .word vector_undef +_vector_swi: .word vector_swi +_vector_pabt: .word vector_pabt +_vector_dabt: .word vector_dabt +_vector_resv: .word vector_resv +_vector_irq: .word vector_irq +_vector_fiq: .word vector_fiq + + .balignl 16,0xdeadbeef + +_TEXT_BASE: + .word TEXT_BASE + +/* + * rtthread kernel start and end + * which are defined in linker script + */ +.globl _rtthread_start +_rtthread_start:.word _start +.globl _rtthread_end +_rtthread_end: .word _end + +/* + * rtthread bss start and end + * which are defined in linker script + */ +.globl _bss_start +_bss_start: .word __bss_start +.globl _bss_end +_bss_end: .word __bss_end + +/* IRQ stack memory (calculated at run-time) */ +.globl IRQ_STACK_START +IRQ_STACK_START:.word _irq_stack_start + 1024 +.globl FIQ_STACK_START +FIQ_STACK_START:.word _fiq_stack_start + 1024 +.globl UNDEFINED_STACK_START +UNDEFINED_STACK_START:.word _undefined_stack_start + CONFIG_STACKSIZE +.globl ABORT_STACK_START +ABORT_STACK_START:.word _abort_stack_start + CONFIG_STACKSIZE +.globl _STACK_START +_STACK_START:.word _svc_stack_start + 4096 + + .equ RAM_BASE, 0x00000000 //Start address of RAM + .equ ROM_BASE, 0x30000000 //Start address of Flash + + .equ INTMSK, 0x4a000008 + .equ WTCON, 0x53000000 + .equ INTSUBMSK, 0x4a00001c + .equ LOCKTIME, 0x4c000000 + + .equ MPLLCON, 0x4c000004 + .equ M_MDIV, 0x20 + .equ M_PDIV, 0x4 + .equ M_SDIV, 0x2 + .equ CLKDIVN, 0x4c000014 //Clock divider control + .equ GPHCON, 0x56000070 //Port H control + .equ GPHUP, 0x56000078 //Pull-up control H + .equ BWSCON, 0x48000000 //Bus width & wait status + .equ BANKCON0, 0x48000004 //Boot ROM control + .equ BANKCON1, 0x48000008 //BANK1 control + .equ BANKCON2, 0x4800000c //BANK2 cControl + .equ BANKCON3, 0x48000010 //BANK3 control + .equ BANKCON4, 0x48000014 //BANK4 control + .equ BANKCON5, 0x48000018 //BANK5 control + .equ BANKCON6, 0x4800001c //BANK6 control + .equ BANKCON7, 0x48000020 //BANK7 control + .equ REFRESH, 0x48000024 //DRAM/SDRAM efresh + .equ BANKSIZE, 0x48000028 //Flexible Bank Size + .equ MRSRB6, 0x4800002c //Mode egister set for SDRAM + .equ MRSRB7, 0x48000030 //Mode egister set for SDRAM + +/* -----------------entry--------------- */ +reset: + /* watch dog disable */ + ldr r0,=WTCON + ldr r1,=0x0 + str r1,[r0] + + /* set the cpu to SVC32 mode */ + mrs r0,cpsr + bic r0,r0,#MODEMASK + orr r0,r0,#SVCMODE + msr cpsr,r0 + + /* mask all IRQs by clearing all bits in the INTMRs */ + ldr r1, =INTMSK + ldr r0, =0xffffffff + str r0, [r1] + + /* set interrupt vector */ + ldr r0, _load_address + mov r1, #0x0 /* target address */ + add r2, r0, #0x20 /* size, 32bytes */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + ble copy_loop + + /* setup stack */ + bl stack_setup + + /* clear .bss */ + mov r0,#0 /* get a zero */ + ldr r1,=__bss_start /* bss start */ + ldr r2,=__bss_end /* bss end */ +bss_loop: + cmp r1,r2 /* check if data to clear */ + strlo r0,[r1],#4 /* clear 4 bytes */ + blo bss_loop /* loop until done */ + + /* call C++ constructors of global objects */ + ldr r0, =__ctors_start__ + ldr r1, =__ctors_end__ +ctor_loop: + cmp r0, r1 + beq ctor_end + ldr r2, [r0], #4 + stmfd sp!, {r0-r1} + mov lr, pc + bx r2 + ldmfd sp!, {r0-r1} + b ctor_loop +ctor_end: + + /* start RT-Thread Kernel */ + ldr pc, _rtthread_startup + +_rtthread_startup: .word rtthread_startup +#if defined (__FLASH_BUILD__) +_load_address: .word ROM_BASE + _TEXT_BASE +#else +_load_address: .word RAM_BASE + _TEXT_BASE +#endif + +/* + ************************************************************************* + * + * Interrupt handling + * + ************************************************************************* + */ + +/* exception handlers */ + .align 5 +vector_undef: + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r8, sp, #S_PC + stmdb r8, {sp, lr}^ @ Calling SP, LR + str lr, [r8, #0] @ Save calling PC + mrs r6, spsr + str r6, [r8, #4] @ Save CPSR + str r0, [r8, #8] @ Save OLD_R0 + mov r0, sp + + bl rt_hw_trap_udef + + .align 5 +vector_swi: + bl rt_hw_trap_swi + + .align 5 +vector_pabt: + bl rt_hw_trap_pabt + + .align 5 +vector_dabt: + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r8, sp, #S_PC + stmdb r8, {sp, lr}^ @ Calling SP, LR + str lr, [r8, #0] @ Save calling PC + mrs r6, spsr + str r6, [r8, #4] @ Save CPSR + str r0, [r8, #8] @ Save OLD_R0 + mov r0, sp + + bl rt_hw_trap_dabt + + .align 5 +vector_resv: + bl rt_hw_trap_resv + +.globl rt_interrupt_enter +.globl rt_interrupt_leave +.globl rt_thread_switch_interrput_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread +vector_irq: + stmfd sp!, {r0-r12,lr} + bl rt_interrupt_enter + bl rt_hw_trap_irq + bl rt_interrupt_leave + + /* if rt_thread_switch_interrput_flag set, jump to _interrupt_thread_switch and don't return */ + ldr r0, =rt_thread_switch_interrput_flag + ldr r1, [r0] + cmp r1, #1 + beq _interrupt_thread_switch + + ldmfd sp!, {r0-r12,lr} + subs pc, lr, #4 + + .align 5 +vector_fiq: + stmfd sp!,{r0-r7,lr} + bl rt_hw_trap_fiq + ldmfd sp!,{r0-r7,lr} + subs pc,lr,#4 + +_interrupt_thread_switch: + mov r1, #0 @ clear rt_thread_switch_interrput_flag + str r1, [r0] + + ldmfd sp!, {r0-r12,lr}@ reload saved registers + stmfd sp!, {r0-r3} @ save r0-r3 + mov r1, sp + add sp, sp, #16 @ restore sp + sub r2, lr, #4 @ save old task's pc to r2 + + mrs r3, spsr @ disable interrupt + orr r0, r3, #NOINT + msr spsr_c, r0 + + ldr r0, =.+8 @ switch to interrupted task's stack + movs pc, r0 + + stmfd sp!, {r2} @ push old task's pc + stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 + mov r4, r1 @ Special optimised code below + mov r5, r3 + ldmfd r4!, {r0-r3} + stmfd sp!, {r0-r3} @ push old task's r3-r0 + stmfd sp!, {r5} @ push old task's psr + mrs r4, spsr + stmfd sp!, {r4} @ push old task's spsr + + ldr r4, =rt_interrupt_from_thread + ldr r5, [r4] + str sp, [r5] @ store sp in preempted tasks's TCB + + ldr r6, =rt_interrupt_to_thread + ldr r6, [r6] + ldr sp, [r6] @ get new task's stack pointer + + ldmfd sp!, {r4} @ pop new task's spsr + msr SPSR_cxsf, r4 + ldmfd sp!, {r4} @ pop new task's psr + msr CPSR_cxsf, r4 + + ldmfd sp!, {r0-r12,lr,pc} @ pop new task's r0-r12,lr & pc + +stack_setup: + mrs r0, cpsr + bic r0, r0, #MODEMASK + orr r1, r0, #UNDEFMODE|NOINT + msr cpsr_cxsf, r1 @ undef mode + ldr sp, UNDEFINED_STACK_START + + orr r1,r0,#ABORTMODE|NOINT + msr cpsr_cxsf,r1 @ abort mode + ldr sp, ABORT_STACK_START + + orr r1,r0,#IRQMODE|NOINT + msr cpsr_cxsf,r1 @ IRQ mode + ldr sp, IRQ_STACK_START + + orr r1,r0,#FIQMODE|NOINT + msr cpsr_cxsf,r1 @ FIQ mode + ldr sp, FIQ_STACK_START + + bic r0,r0,#MODEMASK + orr r1,r0,#SVCMODE|NOINT + msr cpsr_cxsf,r1 @ SVC mode + + ldr sp, _STACK_START + + /* USER mode is not initialized. */ + + mov pc,lr @ The LR register may be not valid for the mode changes. + +/*@}*/