.global _start
.global copy_myself1
.extern main
.extern led_gpio_setup
.extern led2_light
.extern timer0_irq_c
.extern led1_off
.extern test
.extern main2
.extern uart0_puts
.extern load
_start:
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
_pad: .word 0x12345678
.align 4
undefined_instruction:
ldr sp,=(0x8000);
adr r0,undefined_instruction_isr_string
bl uart0_puts
b .
software_interrupt:
ldr sp,=(0x8000-0x200);
adr r0,software_interrupt_isr_string
bl uart0_puts
b .
prefetch_abort:
ldr sp,=(0x8000-0x200);
adr r0,prefetch_abort_isr_string
bl uart0_puts
b .
data_abort:
ldr sp,=(0x8000-0x200);
adr r0,data_abort_isr_string
bl uart0_puts
b .
not_used:
fiq:
ldr sp,=(0x8000-0x200);
adr r0,fiq_isr_sring
bl uart0_puts
b .
.align 4
fiq_isr_sring:
.ascii "fiq isr\n"
.align 4
data_abort_isr_string:
.ascii "data_abort isr string\n"
.align 4
prefetch_abort_isr_string:
.ascii "prefetch_abort\n"
.align 4
software_interrupt_isr_string:
.ascii "software_interrupt\n"
.align 4
undefined_instruction_isr_string:
.ascii "undefined_instruction\n"
.align 4
irq_isr_string:
.ascii "irq request\n"
.align 4
irq:
ldr sp,=0x8000;
stmfd sp!,{r0-r12,lr}
adr r0,irq_isr_string
bl uart0_puts
bl timer0_irq_c;
ldmfd sp!,{r0-r12,lr}
subs pc,lr,#4;/*return from exception*/
reset:
mrs r0,cpsr;
orr r0,r0,#(0x3<<6);/*disable the fiq and irq*/
bic r0,r0,#0x1f
orr r0,r0,#0x13;/*turn to svc mode*/
bl cpu_init_cp15;/*mmu setup(diable mmu and related cache)*/
bl setup_sp;/*setup stack pointer(SP)*/
bl irq_stack_setup;
bl led_gpio_setup;
mrs r0,cpsr /*open the irq and fiq*/
bic r0,r0,#(0x3<<6);
msr cpsr,r0
adr r0,_start
mrc p15,0,r1,c1,c0,0
mrc p15,0,r2,c12,c0,0
mrc p15,0,r3,c12,c0,1
b main;
irq_stack_setup:
mov r1,sp;
mrs r2,cpsr;/*save the cpsr*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0x12;/*turn to the irq mode*/
msr cpsr,r0;/*then we are in the irq mode*/
mov sp,r1;
msr cpsr,r2;/* restore the cpsr*/
sub r1,r1,#0x400 ;/*0x100:reserve irq stack size*/
mov sp,r1;
mov pc,lr;
cpu_init_cp15:
/*
* Invalidate L1 I/D
*/
mov r0, #0 @ set up for MCR
mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
#ifdef CONFIG_SYS_ICACHE_OFF
bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
#else
orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
#endif
mcr p15, 0, r0, c1, c0, 0
mov pc, lr @ back to my caller
.equ CONFIG_SYS_INIT_SP_ADDR,0x8000
setup_sp:
ldr r0,=CONFIG_SYS_INIT_SP_ADDR;
mov sp,r0;
mov pc,lr;
copy_myself:
mov r0,lr
mov r1,pc
mov r2,r4
adr r3,_start
bl test
b .
copy_myself1:
.equ RELOCATION_ADDR,0x2000
stmfd sp!,{r0-r4}
ldr r0,=RELOCATION_ADDR;/*destination*/
adr r1,_start/*copy of start*/
mov r4,r1;/*save the offset*/
ldr r2,=0x1000
copy_loop1:
ldr r3,[r1]
str r3,[r0]
add r1,r1,#4
add r0,r0,#4
cmp r1,r2
bls copy_loop1;/*complete copying*/
adr r1,copy_myself2;
sub r1,r1,r4;
add r1,r1,#RELOCATION_ADDR
mov pc,r1
copy_myself2:
stmfd sp!,{r0-r4,lr}
bl led2_light
ldmfd sp!,{r0-r4,lr}
ldr r0,=0x0;/* destination*/
ldr r1,=RELOCATION_ADDR; /*source */
ldr r2,=0x1000;
copy_loop2:
ldr r3,[r1];
str r3,[r0];
add r0,r0,#4;
add r1,r1,#4;
cmp r0,r2
bls copy_loop2
stmfd sp!,{r0-r4,lr}
bl load
ldmfd sp!,{r0-r4,lr}
stmfd sp!,{r0-r4,lr}
mov r0,lr
mov r1,pc
mov r2,r4
adr r3,_start
bl test
ldmfd sp!,{r0-r4,lr}
ldr r0,=0x0000
mcr p15,0,r0,c12,c0,0
sub lr,lr,r4;
add lr,lr,#RELOCATION_ADDR
ldmfd sp!,{r0-r4}
mov pc,lr