start_gcc.S 5.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
/*
 * File      : start_gcc.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://www.rt-thread.org/license/LICENSE
 *
 * Change Logs:
 * Date           Author       Notes
 * 2006-08-31     Bernard      first version
 */

	/* Internal Memory Base Addresses */
	.equ    FLASH_BASE,     0x00100000   
	.equ    RAM_BASE,       0x00200000

	/* Stack Configuration */
	.equ    TOP_STACK,      0x00204000
	.equ    UND_STACK_SIZE, 0x00000100
	.equ    SVC_STACK_SIZE, 0x00000400
	.equ    ABT_STACK_SIZE, 0x00000100
	.equ    FIQ_STACK_SIZE, 0x00000100
	.equ    IRQ_STACK_SIZE, 0x00000100
	.equ    USR_STACK_SIZE, 0x00000004

	/* ARM architecture definitions */
	.equ	MODE_USR, 0x10
	.equ	MODE_FIQ, 0x11
	.equ	MODE_IRQ, 0x12
	.equ	MODE_SVC, 0x13
	.equ	MODE_ABT, 0x17
	.equ	MODE_UND, 0x1B
	.equ	MODE_SYS, 0x1F

	.equ    I_BIT, 0x80    /* when this bit is set, IRQ is disabled */
	.equ    F_BIT, 0x40    /* when this bit is set, FIQ is disabled */

.section .init, "ax"
.code 32
.align 0
.globl _start
_start:
	b	reset
	ldr	pc, _vector_undef
	ldr	pc, _vector_swi
	ldr	pc, _vector_pabt
	ldr	pc, _vector_dabt
	nop							/* reserved vector */
	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

/*
 * 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

/* the system entry */
reset:
	/* disable watchdog */
	ldr r0, =0xFFFFFD40
	ldr r1, =0x00008000
	str r1, [r0, #0x04]
	
	/* enable the main oscillator */
	ldr r0, =0xFFFFFC00
	ldr r1, =0x00000601
	str r1, [r0, #0x20]
	
	/* wait for main oscillator to stabilize */
moscs_loop:
	ldr r2, [r0, #0x68]
	ands r2, r2, #1
	beq moscs_loop
	
	/* set up the PLL */
	ldr r1, =0x00191C05
	str r1, [r0, #0x2C]
	
	/* wait for PLL to lock */
pll_loop:
	ldr r2, [r0, #0x68]
	ands r2, r2, #0x04
	beq pll_loop
	
	/* select clock */
	ldr r1, =0x00000007
	str r1, [r0, #0x30]
	
	/* setup stack for each mode */
	ldr r0, =TOP_STACK
	
	/* set stack */
	/* undefined instruction mode */
	msr cpsr_c, #MODE_UND|I_BIT|F_BIT
	mov sp, r0
	sub r0, r0, #UND_STACK_SIZE
	
	/* abort mode */
	msr cpsr_c, #MODE_ABT|I_BIT|F_BIT
	mov sp, r0
	sub r0, r0, #ABT_STACK_SIZE
	
	/* FIQ mode */
	msr cpsr_c, #MODE_FIQ|I_BIT|F_BIT
	mov sp, r0
	sub r0, r0, #FIQ_STACK_SIZE
	
	/* IRQ mode */
	msr cpsr_c, #MODE_IRQ|I_BIT|F_BIT
	mov sp, r0
	sub r0, r0, #IRQ_STACK_SIZE
	
	/* supervisor mode */
	msr cpsr_c, #MODE_SVC
	mov sp, r0
	
#ifdef __FLASH_BUILD__
	/* Relocate .data section (Copy from ROM to RAM) */
	ldr     r1, =_etext
	ldr     r2, =_data
	ldr     r3, =_edata
data_loop:
	cmp     r2, r3
	ldrlo   r0, [r1], #4
	strlo   r0, [r2], #4
	blo     data_loop
#else
	/* remap SRAM to 0x0000 */
	ldr r0, =0xFFFFFF00
	mov r1, #0x01
	str r1, [r0]
#endif
	
	/* mask all IRQs */
	ldr	r1, =0xFFFFF124
	ldr	r0, =0XFFFFFFFF
	str	r0, [r1]
	
	/* start RT-Thread Kernel */
	ldr	pc, _rtthread_startup
	
_rtthread_startup: .word rtthread_startup

/* exception handlers */
vector_undef: b	vector_undef
vector_swi  : b vector_swi
vector_pabt : b vector_pabt
vector_dabt : b vector_dabt
vector_resv : b vector_resv

.globl rt_interrupt_enter
.globl rt_interrupt_leave
D
dzzxzz 已提交
167
.globl rt_thread_switch_interrupt_flag
168 169 170 171 172 173 174 175 176
.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

	/* 
D
dzzxzz 已提交
177
	 * if rt_thread_switch_interrupt_flag set, jump to
178 179
	 * rt_hw_context_switch_interrupt_do and don't return
	 */
D
dzzxzz 已提交
180
	ldr	r0, =rt_thread_switch_interrupt_flag
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
	ldr	r1, [r0]
	cmp	r1, #1
	beq	rt_hw_context_switch_interrupt_do

	ldmfd	sp!, {r0-r12,lr}
	subs	pc, lr, #4

vector_fiq:
	stmfd	sp!,{r0-r7,lr}
	bl 	rt_hw_trap_fiq
	ldmfd	sp!,{r0-r7,lr}
	subs	pc,lr,#4

/*
 * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
 */
rt_hw_context_switch_interrupt_do:
	mov		r1,  #0				/* clear 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, #I_BIT|F_BIT
	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 */