I am trying to use interrupt on cubieboard a10(with allwinner 10).i relocation 
the vector table to 0x00000000(cp15,c12 is set to 0x0).but when the timer0 
interrupt is triggered,it stops to run...
but when i try to relocte it to 0x4000.everything goes all right.i have been 
searching for a few days about this proble but fail to find what is wrong.
here is part of my code(quite rough):
.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
        
/*just print r0,r1,r2,r3 when jump to main*/
        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_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 of _start to 0x0(because of the 
mksunxiboot*/
                ldr r2,=0x1000/*break copying when r1 reach this point */
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
/*now we are running at new position*/
/*i want to copy back to 0x000*/
copy_myself2:
        
        stmfd sp!,{r0-r4,lr}
        bl led2_light
        ldmfd sp!,{r0-r4,lr}
        
        ldr r0,=0x0;/* destination*/
        ldr r1,=RELOCATION_ADDR; /*start */
        ldr r2,=0x1000; /*copy length*/
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 /*this function is used to print the content of 0x0 to 0x1000*/
        ldmfd sp!,{r0-r4,lr}
        
        stmfd sp!,{r0-r4,lr}
        mov r0,lr
        mov r1,pc
        mov r2,r4
        adr r3,_start
        bl test /*print content of some registers*/
        ldmfd sp!,{r0-r4,lr}

        ldr r0,=0x0000 /*set the vector table base address*/
        mcr p15,0,r0,c12,c0,0
        
        sub lr,lr,r4;/because the _start doesn't equals 0x0 at first. r4 is the 
offset of _start to 0x00000000.*/

        ldmfd sp!,{r0-r4}
/* restore registers */
        mov pc,lr
        
        

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to