314 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
		
		
			
		
	
	
			314 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
|   | /* | ||
|  |  * start.S | ||
|  |  * | ||
|  |  * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com>
 | ||
|  |  * Official site: http://xboot.org | ||
|  |  * Mobile phone: +86-18665388956 | ||
|  |  * QQ: 8192542 | ||
|  |  * | ||
|  |  * This program is free software; you can redistribute it and/or modify
 | ||
|  |  * it under the terms of the GNU General Public License as published by | ||
|  |  * the Free Software Foundation; either version 2 of the License, or
 | ||
|  |  * (at your option) any later version. | ||
|  |  * | ||
|  |  * This program is distributed in the hope that it will be useful, | ||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||
|  |  * GNU General Public License for more details. | ||
|  |  * | ||
|  |  * You should have received a copy of the GNU General Public License | ||
|  |  * along with this program; if not, write to the Free Software Foundation,
 | ||
|  |  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||
|  |  * | ||
|  |  */ | ||
|  | 
 | ||
|  | /* | ||
|  |  * Exception vector table | ||
|  |  */ | ||
|  | .text | ||
|  | 	.arm | ||
|  | 
 | ||
|  | 	.global	_start
 | ||
|  | _start: | ||
|  | 	/* Boot head information for BROM */ | ||
|  | 	.long 0xea000016
 | ||
|  | 	.byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' | ||
|  | 	.long 0, __bootloader_size | ||
|  | 	.byte 'S', 'P', 'L', 2 | ||
|  | 	.long 0, 0 | ||
|  | 	.long 0, 0, 0, 0, 0, 0, 0, 0 | ||
|  | 	.long 0, 0, 0, 0, 0, 0, 0, 0	/* 0x40 - boot params, 0x58 - fel boot type, 0x5c - dram size */ | ||
|  | 
 | ||
|  | _vector: | ||
|  | 	b reset | ||
|  | 	ldr pc, _undefined_instruction | ||
|  | 	ldr pc, _software_interrupt | ||
|  | 	ldr pc, _prefetch_abort | ||
|  | 	ldr pc, _data_abort | ||
|  | 	ldr pc, _not_used | ||
|  | 	ldr pc, _irq | ||
|  | 	ldr pc, _fiq | ||
|  | 
 | ||
|  | _undefined_instruction: | ||
|  | 	.word undefined_instruction
 | ||
|  | _software_interrupt: | ||
|  | 	.word software_interrupt
 | ||
|  | _prefetch_abort: | ||
|  | 	.word prefetch_abort
 | ||
|  | _data_abort: | ||
|  | 	.word data_abort
 | ||
|  | _not_used: | ||
|  | 	.word not_used
 | ||
|  | _irq: | ||
|  | 	.word irq
 | ||
|  | _fiq: | ||
|  | 	.word fiq
 | ||
|  | 
 | ||
|  | /* | ||
|  |  * The actual reset code | ||
|  |  */ | ||
|  | reset: | ||
|  | 	/* Save boot params to 0x00000040 */ | ||
|  | 	ldr r0, =0x00000040 | ||
|  | 	str sp, [r0, #0] | ||
|  | 	str lr, [r0, #4] | ||
|  | 	mrs lr, cpsr | ||
|  | 	str lr, [r0, #8] | ||
|  | 	mrc p15, 0, lr, c1, c0, 0 | ||
|  | 	str lr, [r0, #12] | ||
|  | 	mrc p15, 0, lr, c1, c0, 0 | ||
|  | 	str lr, [r0, #16] | ||
|  | 
 | ||
|  | 	/* Check boot type just for fel */ | ||
|  | 	mov r0, #0x0 | ||
|  | 	ldr r1, [r0, #8] | ||
|  | 	ldr r2, =0x4c45462e | ||
|  | 	cmp r1, r2 | ||
|  | 	bne 1f | ||
|  | 	ldr r1, =0x1 | ||
|  | 	str r1, [r0, #0x58] | ||
|  | 1:	nop | ||
|  | 
 | ||
|  | 	/* Enter svc mode and mask interrupts */ | ||
|  | 	mrs r0, cpsr | ||
|  | 	bic r0, r0, #0x1f | ||
|  | 	orr r0, r0, #0xd3 | ||
|  | 	msr cpsr, r0 | ||
|  | 
 | ||
|  | 	/* Set vector to the low address */ | ||
|  | 	mrc p15, 0, r0, c1, c0, 0 | ||
|  | 	bic r0, #(1<<13) | ||
|  | 	mcr p15, 0, r0, c1, c0, 0 | ||
|  | 
 | ||
|  | 	/* Copy vector to the correct address */ | ||
|  | 	adr r0, _vector | ||
|  | 	mrc p15, 0, r2, c1, c0, 0 | ||
|  | 	ands r2, r2, #(1 << 13) | ||
|  | 	ldreq r1, =0x00000000 | ||
|  | 	ldrne r1, =0xffff0000 | ||
|  | 	ldmia r0!, {r2-r8, r10} | ||
|  | 	stmia r1!, {r2-r8, r10} | ||
|  | 	ldmia r0!, {r2-r8, r10} | ||
|  | 	stmia r1!, {r2-r8, r10} | ||
|  | 
 | ||
|  | 	/* Initial system clock, ddr add uart */ | ||
|  | 	bl sys_clock_init | ||
|  | 	bl sys_dram_init | ||
|  | 	bl sys_uart_init | ||
|  | 
 | ||
|  | 	/* Boot speed up, leave slower sram */ | ||
|  | 	adr r0, _start | ||
|  | 	ldr r1, =_start | ||
|  | 	cmp r0, r1 | ||
|  | 	beq _speedup | ||
|  | 	ldr r0, =0x81f80000 | ||
|  | 	adr r1, _start | ||
|  | 	mov r2, #0x4000 | ||
|  | 	bl memcpy | ||
|  | 	ldr r0, =_speedup | ||
|  | 	ldr r1, =_start | ||
|  | 	sub r0, r0, r1 | ||
|  | 	ldr r1, =0x81f80000 | ||
|  | 	add r0, r0, r1 | ||
|  | 	mov pc, r0 | ||
|  | _speedup: | ||
|  | 	nop | ||
|  | 
 | ||
|  | 	/* Copyself to link address */ | ||
|  | 	adr r0, _start | ||
|  | 	ldr r1, =_start | ||
|  | 	cmp r0, r1 | ||
|  | 	beq 1f | ||
|  | 	bl sys_copyself | ||
|  | 1:	nop | ||
|  | 
 | ||
|  | 	/* Initialize stacks */ | ||
|  | 	mrs r0, cpsr | ||
|  | 	bic r0, r0, #0x1f | ||
|  | 	orr r1, r0, #0x1b | ||
|  | 	msr cpsr_cxsf, r1 | ||
|  | 	ldr sp, _stack_und_end | ||
|  | 
 | ||
|  | 	bic r0, r0, #0x1f | ||
|  | 	orr r1, r0, #0x17 | ||
|  | 	msr cpsr_cxsf, r1 | ||
|  | 	ldr sp, _stack_abt_end | ||
|  | 
 | ||
|  | 	bic r0, r0, #0x1f | ||
|  | 	orr r1, r0, #0x12 | ||
|  | 	msr cpsr_cxsf, r1 | ||
|  | 	ldr sp, _stack_irq_end | ||
|  | 
 | ||
|  | 	bic r0, r0, #0x1f | ||
|  | 	orr r1, r0, #0x11 | ||
|  | 	msr cpsr_cxsf, r1 | ||
|  | 	ldr sp, _stack_fiq_end | ||
|  | 
 | ||
|  | 	bic r0, r0, #0x1f | ||
|  | 	orr r1, r0, #0x13 | ||
|  | 	msr cpsr_cxsf, r1 | ||
|  | 	ldr sp, _stack_srv_end | ||
|  | 
 | ||
|  | 	/* Copy data section */ | ||
|  | 	ldr r0, _data_start | ||
|  | 	ldr r1, _data_shadow_start | ||
|  | 	ldr r2, _data_shadow_end | ||
|  | 	sub r2, r2, r1 | ||
|  | 	bl memcpy | ||
|  | 
 | ||
|  | 	/* Clear bss section */ | ||
|  | 	ldr r0, _bss_start | ||
|  | 	ldr r2, _bss_end | ||
|  | 	sub r2, r2, r0 | ||
|  | 	mov r1, #0 | ||
|  | 	bl memset | ||
|  | 
 | ||
|  | 	/* Call _main */ | ||
|  | 	ldr r1, =_main | ||
|  | 	mov pc, r1 | ||
|  | _main: | ||
|  | 	bl main | ||
|  | 	b _main | ||
|  | 
 | ||
|  | 	.global return_to_fel
 | ||
|  | return_to_fel: | ||
|  | 	mov r0, #0x4 | ||
|  | 	mov r1, #'e' | ||
|  | 	strb r1, [r0, #0] | ||
|  | 	mov r1, #'G' | ||
|  | 	strb r1, [r0, #1] | ||
|  | 	mov r1, #'O' | ||
|  | 	strb r1, [r0, #2] | ||
|  | 	mov r1, #'N' | ||
|  | 	strb r1, [r0, #3] | ||
|  | 	mov r1, #'.' | ||
|  | 	strb r1, [r0, #4] | ||
|  | 	mov r1, #'F' | ||
|  | 	strb r1, [r0, #5] | ||
|  | 	mov r1, #'E' | ||
|  | 	strb r1, [r0, #6] | ||
|  | 	mov r1, #'L' | ||
|  | 	strb r1, [r0, #7] | ||
|  | 	ldr r0, =0x00000040 | ||
|  | 	ldr sp, [r0, #0] | ||
|  | 	ldr lr, [r0, #4] | ||
|  | 	ldr r1, [r0, #16] | ||
|  | 	mcr p15, 0, r1, c1, c0, 0 | ||
|  | 	ldr r1, [r0, #12] | ||
|  | 	mcr p15, 0, r1, c1, c0, 0 | ||
|  | 	ldr r1, [r0, #8] | ||
|  | 	msr cpsr, r1 | ||
|  | 	bx lr | ||
|  | 
 | ||
|  | /* | ||
|  |  * Exception handlers | ||
|  |  */ | ||
|  | 	.align 5
 | ||
|  | undefined_instruction: | ||
|  | 	b . | ||
|  | 
 | ||
|  | 	.align 5
 | ||
|  | software_interrupt: | ||
|  | 	b . | ||
|  | 
 | ||
|  | 	.align 5
 | ||
|  | prefetch_abort: | ||
|  | 	b . | ||
|  | 
 | ||
|  | 	.align 5
 | ||
|  | data_abort: | ||
|  | 	b . | ||
|  | 
 | ||
|  | 	.align 5
 | ||
|  | not_used: | ||
|  | 	b . | ||
|  | 
 | ||
|  | 	.align 5
 | ||
|  | irq: | ||
|  | 	ldr sp, _stack_irq_end | ||
|  | 	sub sp, sp, #72 | ||
|  | 	stmia sp, {r0 - r12} | ||
|  | 	add r8, sp, #60 | ||
|  | 	stmdb r8, {sp, lr}^ | ||
|  | 	str lr, [r8, #0] | ||
|  | 	mrs r6, spsr | ||
|  | 	str r6, [r8, #4] | ||
|  | 	str r0, [r8, #8] | ||
|  | 	mov r0, sp | ||
|  | 	bl arm32_do_irq | ||
|  | 	ldmia sp, {r0 - lr}^ | ||
|  | 	mov r0, r0 | ||
|  | 	ldr lr, [sp, #60] | ||
|  | 	add sp, sp, #72 | ||
|  | 	subs pc, lr, #4 | ||
|  | 
 | ||
|  | 	.align 5
 | ||
|  | fiq: | ||
|  | 	ldr sp, _stack_irq_end | ||
|  | 	sub sp, sp, #72 | ||
|  | 	stmia sp, {r0 - r12} | ||
|  | 	add r8, sp, #60 | ||
|  | 	stmdb r8, {sp, lr}^ | ||
|  | 	str lr, [r8, #0] | ||
|  | 	mrs r6, spsr | ||
|  | 	str r6, [r8, #4] | ||
|  | 	str r0, [r8, #8] | ||
|  | 	mov r0, sp | ||
|  | 	bl arm32_do_fiq | ||
|  | 	ldmia sp, {r0 - lr}^ | ||
|  | 	mov r0, r0 | ||
|  | 	ldr lr, [sp, #60] | ||
|  | 	add sp, sp, #72 | ||
|  | 	subs pc, lr, #4 | ||
|  | 
 | ||
|  | /* | ||
|  |  * The location of section | ||
|  |  */ | ||
|  |  	.align 4
 | ||
|  | _image_start: | ||
|  | 	.long __image_start
 | ||
|  | _image_end: | ||
|  | 	.long __image_end
 | ||
|  | _data_shadow_start: | ||
|  | 	.long __data_shadow_start
 | ||
|  | _data_shadow_end: | ||
|  | 	.long __data_shadow_end
 | ||
|  | _data_start: | ||
|  | 	.long __data_start
 | ||
|  | _data_end: | ||
|  | 	.long __data_end
 | ||
|  | _bss_start: | ||
|  | 	.long __bss_start
 | ||
|  | _bss_end: | ||
|  | 	.long __bss_end
 | ||
|  | _stack_und_end: | ||
|  | 	.long __stack_und_end
 | ||
|  | _stack_abt_end: | ||
|  | 	.long __stack_abt_end
 | ||
|  | _stack_irq_end: | ||
|  | 	.long __stack_irq_end
 | ||
|  | _stack_fiq_end: | ||
|  | 	.long __stack_fiq_end
 | ||
|  | _stack_srv_end: | ||
|  | 	.long __stack_srv_end
 |