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
 |