espressif_tinyusb/hw/mcu/allwinner/f1c100s/machine/start.S

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