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
							 |