331 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
		
		
			
		
	
	
			331 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Copyright (c) 2006-2018, RT-Thread Development Team
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * SPDX-License-Identifier: Apache-2.0
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Change Logs:
							 | 
						||
| 
								 | 
							
								 * Date           Author       Notes
							 | 
						||
| 
								 | 
							
								 * 2011-01-13     weety      first version
							 | 
						||
| 
								 | 
							
								 * 2015-04-15     ArdaFu     Split from AT91SAM9260 BSP
							 | 
						||
| 
								 | 
							
								 * 2015-04-21     ArdaFu     Remove remap code. Using mmu to map vector table
							 | 
						||
| 
								 | 
							
								 * 2015-06-04     aozima     Align stack address to 8 byte.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.equ MODE_USR,        0x10
							 | 
						||
| 
								 | 
							
								.equ MODE_FIQ,        0x11
							 | 
						||
| 
								 | 
							
								.equ MODE_IRQ,        0x12
							 | 
						||
| 
								 | 
							
								.equ MODE_SVC,        0x13
							 | 
						||
| 
								 | 
							
								.equ MODE_ABT,        0x17
							 | 
						||
| 
								 | 
							
								.equ MODE_UND,        0x1B
							 | 
						||
| 
								 | 
							
								.equ MODE_SYS,        0x1F
							 | 
						||
| 
								 | 
							
								.equ MODEMASK,        0x1F
							 | 
						||
| 
								 | 
							
								.equ NOINT,           0xC0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.equ I_BIT,           0x80
							 | 
						||
| 
								 | 
							
								.equ F_BIT,           0x40
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.equ UND_STACK_SIZE,  0x00000100
							 | 
						||
| 
								 | 
							
								.equ SVC_STACK_SIZE,  0x00000100
							 | 
						||
| 
								 | 
							
								.equ ABT_STACK_SIZE,  0x00000100
							 | 
						||
| 
								 | 
							
								.equ FIQ_STACK_SIZE,  0x00000100
							 | 
						||
| 
								 | 
							
								.equ IRQ_STACK_SIZE,  0x00000100
							 | 
						||
| 
								 | 
							
								.equ SYS_STACK_SIZE,  0x00000100
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 /*
							 | 
						||
| 
								 | 
							
								 ***************************************
							 | 
						||
| 
								 | 
							
								 * Interrupt vector table
							 | 
						||
| 
								 | 
							
								 ***************************************
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								.section .vectors
							 | 
						||
| 
								 | 
							
								.code 32
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.global system_vectors
							 | 
						||
| 
								 | 
							
								system_vectors:
							 | 
						||
| 
								 | 
							
								    ldr pc, _vector_reset
							 | 
						||
| 
								 | 
							
								    ldr pc, _vector_undef
							 | 
						||
| 
								 | 
							
								    ldr pc, _vector_swi
							 | 
						||
| 
								 | 
							
								    ldr pc, _vector_pabt
							 | 
						||
| 
								 | 
							
								    ldr pc, _vector_dabt
							 | 
						||
| 
								 | 
							
								    ldr pc, _vector_resv
							 | 
						||
| 
								 | 
							
								    ldr pc, _vector_irq
							 | 
						||
| 
								 | 
							
								    ldr pc, _vector_fiq
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								_vector_reset:
							 | 
						||
| 
								 | 
							
								    .word reset
							 | 
						||
| 
								 | 
							
								_vector_undef:
							 | 
						||
| 
								 | 
							
								    .word vector_undef
							 | 
						||
| 
								 | 
							
								_vector_swi:
							 | 
						||
| 
								 | 
							
								    .word vector_swi
							 | 
						||
| 
								 | 
							
								_vector_pabt:
							 | 
						||
| 
								 | 
							
								    .word vector_pabt
							 | 
						||
| 
								 | 
							
								_vector_dabt:
							 | 
						||
| 
								 | 
							
								    .word vector_dabt
							 | 
						||
| 
								 | 
							
								_vector_resv:
							 | 
						||
| 
								 | 
							
								    .word vector_resv
							 | 
						||
| 
								 | 
							
								_vector_irq:
							 | 
						||
| 
								 | 
							
								    .word vector_irq
							 | 
						||
| 
								 | 
							
								_vector_fiq:
							 | 
						||
| 
								 | 
							
								    .word vector_fiq
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.balignl    16,0xdeadbeef
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 /*
							 | 
						||
| 
								 | 
							
								 ***************************************
							 | 
						||
| 
								 | 
							
								 *  Stack and Heap Definitions 
							 | 
						||
| 
								 | 
							
								 ***************************************
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								    .section .data
							 | 
						||
| 
								 | 
							
								    .space UND_STACK_SIZE
							 | 
						||
| 
								 | 
							
								    .align 3
							 | 
						||
| 
								 | 
							
								    .global und_stack_start
							 | 
						||
| 
								 | 
							
								und_stack_start:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    .space ABT_STACK_SIZE
							 | 
						||
| 
								 | 
							
								    .align 3
							 | 
						||
| 
								 | 
							
								    .global abt_stack_start
							 | 
						||
| 
								 | 
							
								abt_stack_start:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    .space FIQ_STACK_SIZE
							 | 
						||
| 
								 | 
							
								    .align 3
							 | 
						||
| 
								 | 
							
								    .global fiq_stack_start
							 | 
						||
| 
								 | 
							
								fiq_stack_start:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    .space IRQ_STACK_SIZE
							 | 
						||
| 
								 | 
							
								    .align 3
							 | 
						||
| 
								 | 
							
								    .global irq_stack_start
							 | 
						||
| 
								 | 
							
								irq_stack_start:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    .skip SYS_STACK_SIZE
							 | 
						||
| 
								 | 
							
								    .align 3
							 | 
						||
| 
								 | 
							
								    .global sys_stack_start
							 | 
						||
| 
								 | 
							
								sys_stack_start:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    .space SVC_STACK_SIZE
							 | 
						||
| 
								 | 
							
								    .align 3
							 | 
						||
| 
								 | 
							
								    .global svc_stack_start
							 | 
						||
| 
								 | 
							
								svc_stack_start:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 ***************************************
							 | 
						||
| 
								 | 
							
								 * Startup Code 
							 | 
						||
| 
								 | 
							
								 ***************************************
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								    .section .text
							 | 
						||
| 
								 | 
							
								    .global reset
							 | 
						||
| 
								 | 
							
								reset:
							 | 
						||
| 
								 | 
							
								    /* Enter svc mode and mask interrupts */
							 | 
						||
| 
								 | 
							
								    mrs r0, cpsr
							 | 
						||
| 
								 | 
							
								    bic r0, r0, #MODEMASK
							 | 
						||
| 
								 | 
							
								    orr r0, r0, #MODE_SVC|NOINT
							 | 
						||
| 
								 | 
							
								    msr cpsr_cxsf, r0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* init cpu  */
							 | 
						||
| 
								 | 
							
								    bl  cpu_init_crit
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    /* todo:copyself to link address */
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    /* Copy vector to the correct address */
							 | 
						||
| 
								 | 
							
								    ldr r0, =system_vectors
							 | 
						||
| 
								 | 
							
								    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}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* turn off the watchdog */
							 | 
						||
| 
								 | 
							
								    ldr r0, =0x01C20CB8
							 | 
						||
| 
								 | 
							
								    mov     r1, #0x0
							 | 
						||
| 
								 | 
							
								    str     r1, [r0]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* mask all IRQs source */
							 | 
						||
| 
								 | 
							
								    ldr r1, =0xffffffff
							 | 
						||
| 
								 | 
							
								    ldr r0, =0x01C20430
							 | 
						||
| 
								 | 
							
								    str r1, [r0], #0x04
							 | 
						||
| 
								 | 
							
								    str r1, [r0]
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    /* Call low level init function */
							 | 
						||
| 
								 | 
							
								    ldr     sp, =svc_stack_start
							 | 
						||
| 
								 | 
							
								    ldr     r0, =rt_low_level_init
							 | 
						||
| 
								 | 
							
								    blx     r0
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    /* init stack */
							 | 
						||
| 
								 | 
							
								    bl stack_setup
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    /* clear bss */
							 | 
						||
| 
								 | 
							
								    mov     r0, #0
							 | 
						||
| 
								 | 
							
								    ldr     r1, =__bss_start
							 | 
						||
| 
								 | 
							
								    ldr     r2, =__bss_end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bss_clear_loop:
							 | 
						||
| 
								 | 
							
								    cmp     r1, r2
							 | 
						||
| 
								 | 
							
								    strlo   r0, [r1], #4
							 | 
						||
| 
								 | 
							
								    blo     bss_clear_loop
							 | 
						||
| 
								 | 
							
								       
							 | 
						||
| 
								 | 
							
								    /* call c++ constructors of global objects */
							 | 
						||
| 
								 | 
							
								    /*
							 | 
						||
| 
								 | 
							
								    ldr     r0, =__ctors_start__
							 | 
						||
| 
								 | 
							
								    ldr     r1, =__ctors_end__
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ctor_loop:
							 | 
						||
| 
								 | 
							
								    cmp     r0, r1
							 | 
						||
| 
								 | 
							
								    beq     ctor_end
							 | 
						||
| 
								 | 
							
								    ldr     r2, [r0], #4
							 | 
						||
| 
								 | 
							
								    stmfd   sp!, {r0-r1}
							 | 
						||
| 
								 | 
							
								    mov     lr, pc
							 | 
						||
| 
								 | 
							
								    bx      r2
							 | 
						||
| 
								 | 
							
								    ldmfd   sp!, {r0-r1}
							 | 
						||
| 
								 | 
							
								    b       ctor_loop
							 | 
						||
| 
								 | 
							
								ctor_end:
							 | 
						||
| 
								 | 
							
								    */
							 | 
						||
| 
								 | 
							
								    /* start RT-Thread Kernel */
							 | 
						||
| 
								 | 
							
								    ldr     pc, _rtthread_startup
							 | 
						||
| 
								 | 
							
								_rtthread_startup:
							 | 
						||
| 
								 | 
							
								    .word  rtthread_startup
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cpu_init_crit:
							 | 
						||
| 
								 | 
							
								    /* invalidate I/D caches */
							 | 
						||
| 
								 | 
							
								    mov r0, #0
							 | 
						||
| 
								 | 
							
								    mcr p15, 0, r0, c7, c7, 0
							 | 
						||
| 
								 | 
							
								    mcr p15, 0, r0, c8, c7, 0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* disable MMU stuff and caches */
							 | 
						||
| 
								 | 
							
								    mrc p15, 0, r0, c1, c0, 0
							 | 
						||
| 
								 | 
							
								    bic r0, r0, #0x00002300
							 | 
						||
| 
								 | 
							
								    bic r0, r0, #0x00000087
							 | 
						||
| 
								 | 
							
								    orr r0, r0, #0x00000002
							 | 
						||
| 
								 | 
							
								    orr r0, r0, #0x00001000
							 | 
						||
| 
								 | 
							
								    mcr p15, 0, r0, c1, c0, 0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    bx lr
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								stack_setup:
							 | 
						||
| 
								 | 
							
								    /* Setup Stack for each mode */
							 | 
						||
| 
								 | 
							
								    mrs     r0, cpsr
							 | 
						||
| 
								 | 
							
								    bic     r0, r0, #MODEMASK
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    orr     r1, r0, #MODE_UND|NOINT
							 | 
						||
| 
								 | 
							
								    msr     cpsr_cxsf, r1
							 | 
						||
| 
								 | 
							
								    ldr     sp, =und_stack_start
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    orr     r1, r0, #MODE_ABT|NOINT
							 | 
						||
| 
								 | 
							
								    msr     cpsr_cxsf, r1
							 | 
						||
| 
								 | 
							
								    ldr     sp, =abt_stack_start
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    orr     r1, r0, #MODE_IRQ|NOINT
							 | 
						||
| 
								 | 
							
								    msr     cpsr_cxsf, r1
							 | 
						||
| 
								 | 
							
								    ldr     sp, =irq_stack_start
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    orr     r1, r0, #MODE_FIQ|NOINT
							 | 
						||
| 
								 | 
							
								    msr     cpsr_cxsf, r1
							 | 
						||
| 
								 | 
							
								    ldr     sp, =fiq_stack_start
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    orr     r1, r0, #MODE_SYS|NOINT
							 | 
						||
| 
								 | 
							
								    msr     cpsr_cxsf,r1
							 | 
						||
| 
								 | 
							
								    ldr     sp, =sys_stack_start
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    orr     r1, r0, #MODE_SVC|NOINT
							 | 
						||
| 
								 | 
							
								    msr     cpsr_cxsf, r1
							 | 
						||
| 
								 | 
							
								    ldr     sp, =svc_stack_start
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    bx      lr
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 ***************************************
							 | 
						||
| 
								 | 
							
								 * exception handlers 
							 | 
						||
| 
								 | 
							
								 ***************************************
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								    /* Interrupt */
							 | 
						||
| 
								 | 
							
								vector_fiq:
							 | 
						||
| 
								 | 
							
								    stmfd   sp!,{r0-r7,lr}
							 | 
						||
| 
								 | 
							
								    bl      rt_hw_trap_fiq
							 | 
						||
| 
								 | 
							
								    ldmfd   sp!,{r0-r7,lr}
							 | 
						||
| 
								 | 
							
								    subs    pc, lr, #4
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								vector_irq:
							 | 
						||
| 
								 | 
							
								    stmfd   sp!, {r0-r12,lr}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    bl      rt_interrupt_enter
							 | 
						||
| 
								 | 
							
								    bl      rt_hw_trap_irq
							 | 
						||
| 
								 | 
							
								    bl      rt_interrupt_leave
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ldr     r0, =rt_thread_switch_interrupt_flag
							 | 
						||
| 
								 | 
							
								    ldr     r1, [r0]
							 | 
						||
| 
								 | 
							
								    cmp     r1, #1
							 | 
						||
| 
								 | 
							
								    beq     rt_hw_context_switch_interrupt_do
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ldmfd   sp!, {r0-r12,lr}
							 | 
						||
| 
								 | 
							
								    subs    pc,  lr, #4
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rt_hw_context_switch_interrupt_do:
							 | 
						||
| 
								 | 
							
								    mov     r1,  #0         
							 | 
						||
| 
								 | 
							
								    str     r1,  [r0]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    mov     r1, sp          
							 | 
						||
| 
								 | 
							
								    add     sp, sp, #4*4
							 | 
						||
| 
								 | 
							
								    ldmfd   sp!, {r4-r12,lr}
							 | 
						||
| 
								 | 
							
								    mrs     r0,  spsr       
							 | 
						||
| 
								 | 
							
								    sub     r2,  lr, #4     
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    msr     cpsr_c, #I_BIT|F_BIT|MODE_SVC
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    stmfd   sp!, {r2}       
							 | 
						||
| 
								 | 
							
								    stmfd   sp!, {r4-r12,lr}
							 | 
						||
| 
								 | 
							
								    ldmfd   r1,  {r1-r4}    
							 | 
						||
| 
								 | 
							
								    stmfd   sp!, {r1-r4}    
							 | 
						||
| 
								 | 
							
								    stmfd   sp!, {r0}       
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ldr     r4,  =rt_interrupt_from_thread
							 | 
						||
| 
								 | 
							
								    ldr     r5,  [r4]
							 | 
						||
| 
								 | 
							
								    str     sp,  [r5]       
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ldr     r6,  =rt_interrupt_to_thread
							 | 
						||
| 
								 | 
							
								    ldr     r6,  [r6]
							 | 
						||
| 
								 | 
							
								    ldr     sp,  [r6]       
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ldmfd   sp!, {r4}       
							 | 
						||
| 
								 | 
							
								    msr     spsr_cxsf, r4
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ldmfd   sp!, {r0-r12,lr,pc}^ 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Exception */
							 | 
						||
| 
								 | 
							
								.macro push_svc_reg
							 | 
						||
| 
								 | 
							
								    sub     sp, sp, #17 * 4
							 | 
						||
| 
								 | 
							
								    stmia   sp, {r0 - r12} 
							 | 
						||
| 
								 | 
							
								    mov     r0, sp
							 | 
						||
| 
								 | 
							
								    mrs     r6, spsr       
							 | 
						||
| 
								 | 
							
								    str     lr, [r0, #15*4]
							 | 
						||
| 
								 | 
							
								    str     r6, [r0, #16*4]
							 | 
						||
| 
								 | 
							
								    str     sp, [r0, #13*4]
							 | 
						||
| 
								 | 
							
								    str     lr, [r0, #14*4]
							 | 
						||
| 
								 | 
							
								.endm
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								vector_swi:
							 | 
						||
| 
								 | 
							
								    push_svc_reg
							 | 
						||
| 
								 | 
							
								    bl      rt_hw_trap_swi
							 | 
						||
| 
								 | 
							
								    b       .
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								vector_undef:
							 | 
						||
| 
								 | 
							
								    push_svc_reg
							 | 
						||
| 
								 | 
							
								    bl      rt_hw_trap_udef
							 | 
						||
| 
								 | 
							
								    b       .
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								vector_pabt:
							 | 
						||
| 
								 | 
							
								    push_svc_reg
							 | 
						||
| 
								 | 
							
								    bl      rt_hw_trap_pabt
							 | 
						||
| 
								 | 
							
								    b       .
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								vector_dabt:
							 | 
						||
| 
								 | 
							
								    push_svc_reg
							 | 
						||
| 
								 | 
							
								    bl      rt_hw_trap_dabt
							 | 
						||
| 
								 | 
							
								    b       .
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								vector_resv:
							 | 
						||
| 
								 | 
							
								    push_svc_reg
							 | 
						||
| 
								 | 
							
								    bl      rt_hw_trap_resv
							 | 
						||
| 
								 | 
							
								    b       .
							 |