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       .
 | 
