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
|