313 lines
10 KiB
ArmAsm
313 lines
10 KiB
ArmAsm
.extern main /* ÒýÈëÍⲿCÈë¿Ú */
|
||
|
||
.extern rt_interrupt_enter
|
||
.extern rt_interrupt_leave
|
||
.extern rt_thread_switch_interrupt_flag
|
||
.extern rt_interrupt_from_thread
|
||
.extern rt_interrupt_to_thread
|
||
.extern rt_hw_trap_irq
|
||
|
||
.global start
|
||
.global endless_loop
|
||
.global rt_hw_context_switch_interrupt_do
|
||
|
||
/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */
|
||
.set MODE_USR, 0x10 /* User Mode */
|
||
.set MODE_FIQ, 0x11 /* FIQ Mode */
|
||
.set MODE_IRQ, 0x12 /* IRQ Mode */
|
||
.set MODE_SVC, 0x13 /* Supervisor Mode */
|
||
.set MODE_ABT, 0x17 /* Abort Mode */
|
||
.set MODE_UND, 0x1B /* Undefined Mode */
|
||
.set MODE_SYS, 0x1F /* System Mode */
|
||
|
||
.equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */
|
||
.equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */
|
||
.equ I_Bit, 0x80 /* when I bit is set, IRQ is disabled */
|
||
.equ F_Bit, 0x40 /* when F bit is set, FIQ is disabled */
|
||
|
||
/* VPBDIV definitions*/
|
||
.equ VPBDIV, 0xE01FC100
|
||
.set VPBDIV_VALUE, 0x00000000
|
||
|
||
/* Phase Locked Loop (PLL) definitions*/
|
||
.equ PLL_BASE, 0xE01FC080 /* PLL Base Address */
|
||
.equ PLLCON_OFS, 0x00 /* PLL Control Offset */
|
||
.equ PLLCFG_OFS, 0x04 /* PLL Configuration Offset */
|
||
.equ PLLSTAT_OFS, 0x08 /* PLL Status Offset */
|
||
.equ PLLFEED_OFS, 0x0C /* PLL Feed Offset */
|
||
.equ PLLCON_PLLE, (1<<0) /* PLL Enable */
|
||
.equ PLLCON_PLLC, (1<<1) /* PLL Connect */
|
||
.equ PLLCFG_MSEL, (0x1F<<0) /* PLL Multiplier */
|
||
.equ PLLCFG_PSEL, (0x03<<5) /* PLL Divider */
|
||
.equ PLLSTAT_PLOCK, (1<<10) /* PLL Lock Status */
|
||
.equ PLLCFG_Val, 0x00000024 /* <o1.0..4> MSEL: PLL Multiplier Selection,<o1.5..6> PSEL: PLL Divider Selection */
|
||
|
||
.equ MEMMAP, 0xE01FC040 /*Memory Mapping Control*/
|
||
|
||
|
||
/* Memory Accelerator Module (MAM) definitions*/
|
||
.equ MAM_BASE, 0xE01FC000
|
||
.equ MAMCR_OFS, 0x00
|
||
.equ MAMTIM_OFS, 0x04
|
||
.equ MAMCR_Val, 0x00000002
|
||
.equ MAMTIM_Val, 0x00000004
|
||
|
||
.equ VICIntEnClr, 0xFFFFF014
|
||
.equ VICIntSelect, 0xFFFFF00C
|
||
/************* Ä¿±êÅäÖýáÊø *************/
|
||
|
||
|
||
/* Setup the operating mode & stack.*/
|
||
/* --------------------------------- */
|
||
.global _reset
|
||
_reset:
|
||
.code 32
|
||
.align 0
|
||
|
||
/************************* PLL_SETUP **********************************/
|
||
ldr r0, =PLL_BASE
|
||
mov r1, #0xAA
|
||
mov r2, #0x55
|
||
|
||
/* Configure and Enable PLL */
|
||
mov r3, #PLLCFG_Val
|
||
str r3, [r0, #PLLCFG_OFS]
|
||
mov r3, #PLLCON_PLLE
|
||
str r3, [r0, #PLLCON_OFS]
|
||
str r1, [r0, #PLLFEED_OFS]
|
||
str r2, [r0, #PLLFEED_OFS]
|
||
|
||
/* Wait until PLL Locked */
|
||
PLL_Locked_loop:
|
||
ldr r3, [r0, #PLLSTAT_OFS]
|
||
ands r3, r3, #PLLSTAT_PLOCK
|
||
beq PLL_Locked_loop
|
||
|
||
/* Switch to PLL Clock */
|
||
mov r3, #(PLLCON_PLLE|PLLCON_PLLC)
|
||
str r3, [r0, #PLLCON_OFS]
|
||
str r1, [r0, #PLLFEED_OFS]
|
||
str R2, [r0, #PLLFEED_OFS]
|
||
/************************* PLL_SETUP **********************************/
|
||
|
||
/************************ Setup VPBDIV ********************************/
|
||
ldr r0, =VPBDIV
|
||
ldr r1, =VPBDIV_VALUE
|
||
str r1, [r0]
|
||
/************************ Setup VPBDIV ********************************/
|
||
|
||
/************** Setup MAM **************/
|
||
ldr r0, =MAM_BASE
|
||
mov r1, #MAMTIM_Val
|
||
str r1, [r0, #MAMTIM_OFS]
|
||
mov r1, #MAMCR_Val
|
||
str r1, [r0, #MAMCR_OFS]
|
||
/************** Setup MAM **************/
|
||
|
||
/************************ setup stack *********************************/
|
||
ldr r0, .undefined_stack_top
|
||
sub r0, r0, #4
|
||
msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */
|
||
mov sp, r0
|
||
|
||
ldr r0, .abort_stack_top
|
||
sub r0, r0, #4
|
||
msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
|
||
mov sp, r0
|
||
|
||
ldr r0, .fiq_stack_top
|
||
sub r0, r0, #4
|
||
msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
|
||
mov sp, r0
|
||
|
||
ldr r0, .irq_stack_top
|
||
sub r0, r0, #4
|
||
msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
|
||
mov sp, r0
|
||
|
||
ldr r0, .svc_stack_top
|
||
sub r0, r0, #4
|
||
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */
|
||
mov sp, r0
|
||
/************************ setup stack ********************************/
|
||
|
||
/* copy .data to SRAM */
|
||
ldr r1, =_sidata /* .data start in image */
|
||
ldr r2, =_edata /* .data end in image */
|
||
ldr r3, =_sdata /* sram data start */
|
||
data_loop:
|
||
ldr r0, [r1, #0]
|
||
str r0, [r3]
|
||
|
||
add r1, r1, #4
|
||
add r3, r3, #4
|
||
|
||
cmp r3, r2 /* check if data to clear */
|
||
blo data_loop /* loop until done */
|
||
|
||
/* clear .bss */
|
||
mov r0,#0 /* get a zero */
|
||
ldr r1,=__bss_start /* bss start */
|
||
ldr r2,=__bss_end /* bss end */
|
||
|
||
bss_loop:
|
||
cmp r1,r2 /* check if data to clear */
|
||
strlo r0,[r1],#4 /* clear 4 bytes */
|
||
blo bss_loop /* loop until done */
|
||
|
||
|
||
/* 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:
|
||
|
||
/* enter C code */
|
||
bl main
|
||
|
||
.align 0
|
||
.undefined_stack_top:
|
||
.word _undefined_stack_top
|
||
.abort_stack_top:
|
||
.word _abort_stack_top
|
||
.fiq_stack_top:
|
||
.word _fiq_stack_top
|
||
.irq_stack_top:
|
||
.word _irq_stack_top
|
||
.svc_stack_top:
|
||
.word _svc_stack_top
|
||
/*********************** END Clear BSS ******************************/
|
||
|
||
.section .init,"ax"
|
||
.code 32
|
||
.align 0
|
||
.globl _start
|
||
_start:
|
||
|
||
ldr pc, __start /* reset - _start */
|
||
ldr pc, _undf /* undefined - _undf */
|
||
ldr pc, _swi /* SWI - _swi */
|
||
ldr pc, _pabt /* program abort - _pabt */
|
||
ldr pc, _dabt /* data abort - _dabt */
|
||
.word 0xB8A06F58 /* reserved */
|
||
ldr pc, __IRQ_Handler /* IRQ - read the VIC */
|
||
ldr pc, _fiq /* FIQ - _fiq */
|
||
|
||
__start:.word _reset
|
||
_undf: .word __undf /* undefined */
|
||
_swi: .word __swi /* SWI */
|
||
_pabt: .word __pabt /* program abort */
|
||
_dabt: .word __dabt /* data abort */
|
||
temp1: .word 0
|
||
__IRQ_Handler: .word IRQ_Handler
|
||
_fiq: .word __fiq /* FIQ */
|
||
|
||
__undf: b . /* undefined */
|
||
__swi : b .
|
||
__pabt: b . /* program abort */
|
||
__dabt: b . /* data abort */
|
||
__fiq : b . /* FIQ */
|
||
|
||
/* IRQÈë¿Ú */
|
||
IRQ_Handler :
|
||
stmfd sp!, {r0-r12,lr} /* ¶ÔR0 ¨C R12£¬LR¼Ä´æÆ÷ѹջ */
|
||
bl rt_interrupt_enter /* ֪ͨRT-Thread½øÈëÖжÏģʽ */
|
||
bl rt_hw_trap_irq /* ÏàÓ¦ÖжϷþÎñÀý³Ì´¦Àí */
|
||
bl rt_interrupt_leave /* ; ֪ͨRT-ThreadÒªÀ뿪ÖжÏģʽ */
|
||
|
||
/* Èç¹ûÉèÖÃÁËrt_thread_switch_interrupt_flag£¬½øÐÐÖжÏÖеÄÏß³ÌÉÏÏÂÎÄ´¦Àí */
|
||
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 /* ´ÓIRQÖзµ»Ø */
|
||
|
||
/*
|
||
* void rt_hw_context_switch_interrupt_do(rt_base_t flag)
|
||
* ÖжϽáÊøºóµÄÉÏÏÂÎÄÇл»
|
||
*/
|
||
rt_hw_context_switch_interrupt_do:
|
||
mov r1, #0 /* clear flag */
|
||
/* Çå³þÖжÏÖÐÇл»±êÖ¾ */
|
||
str r1, [r0] /* */
|
||
|
||
ldmfd sp!, {r0-r12,lr}/* reload saved registers */
|
||
/* ÏȻָ´±»ÖжÏÏ̵߳ÄÉÏÏÂÎÄ */
|
||
stmfd sp!, {r0-r3} /* save r0-r3 */
|
||
/* ¶ÔR0 ¨C R3ѹջ£¬ÒòΪºóÃæ»áÓõ½ */
|
||
mov r1, sp /* °Ñ´Ë´¦µÄÕ»Öµ±£´æµ½R1 */
|
||
add sp, sp, #16 /* restore sp */
|
||
/* »Ö¸´IRQµÄÕ»£¬ºóÃæ»áÌø³öIRQģʽ */
|
||
sub r2, lr, #4 /* save old task's pc to r2 */
|
||
/* ±£´æÇл»³öÏ̵߳ÄPCµ½R2 */
|
||
|
||
mrs r3, spsr /* disable interrupt ±£´æÖжÏÇ°µÄCPSRµ½R3¼Ä´æÆ÷ */
|
||
/* »ñµÃSPSR¼Ä´æÆ÷Öµ */
|
||
orr r0, r3, #I_BIT|F_BIT
|
||
msr spsr_c, r0 /* ¹Ø±ÕSPSRÖеÄIRQ/FIQÖÐ¶Ï */
|
||
|
||
ldr r0, =.+8 /* °Ñµ±Ç°µØÖ·+8ÔØÈëµ½R0¼Ä´æÆ÷ÖÐ switch to interrupted task's stack */
|
||
movs pc, r0 /* Í˳öIRQģʽ£¬ÓÉÓÚSPSR±»ÉèÖóɹØÖжÏģʽ */
|
||
/* ËùÒÔ´ÓIRQ·µ»Øºó£¬Öжϲ¢Ã»Óдò¿ª
|
||
; R0¼Ä´æÆ÷ÖеÄλÖÃʵ¼Ê¾ÍÊÇÏÂÒ»ÌõÖ¸Á
|
||
; ¼´PC¼ÌÐøÍùÏÂ×ß
|
||
; ´Ëʱ
|
||
; ģʽÒѾ»»³ÉÖжÏÇ°µÄSVCģʽ£¬
|
||
; SP¼Ä´æÆ÷Ò²ÊÇSVCģʽϵÄÕ»¼Ä´æÆ÷
|
||
; R1±£´æIRQģʽϵÄÕ»Ö¸Õë
|
||
; R2±£´æÇл»³öÏ̵߳ÄPC
|
||
; R3±£´æÇл»³öÏ̵߳ÄCPSR */
|
||
stmfd sp!, {r2} /* push old task's pc */
|
||
/* ±£´æÇл»³öÈÎÎñµÄPC */
|
||
stmfd sp!, {r4-r12,lr}/* push old task's lr,r12-r4 */
|
||
/* ±£´æR4 ¨C R12£¬LR¼Ä´æÆ÷ */
|
||
mov r4, r1 /* Special optimised code below */
|
||
/* R1±£´æÓÐѹջR0 ¨C R3´¦µÄջλÖà */
|
||
mov r5, r3 /* R3Çл»³öÏ̵߳ÄCPSR */
|
||
ldmfd r4!, {r0-r3} /* »Ö¸´R0 ¨C R3 */
|
||
stmfd sp!, {r0-r3} /* push old task's r3-r0 */
|
||
/* R0 ¨C R3ѹջµ½Çл»³öÏß³Ì */
|
||
stmfd sp!, {r5} /* push old task's psr */
|
||
/* Çл»³öÏß³ÌCPSRѹջ */
|
||
mrs r4, spsr
|
||
stmfd sp!, {r4} /* push old task's spsr */
|
||
/* Çл»³öÏß³ÌSPSRѹջ */
|
||
|
||
ldr r4, =rt_interrupt_from_thread
|
||
ldr r5, [r4]
|
||
str sp, [r5] /* store sp in preempted tasks's TCB */
|
||
/* ±£´æÇл»³öÏ̵߳ÄSPÖ¸Õë */
|
||
|
||
ldr r6, =rt_interrupt_to_thread
|
||
ldr r6, [r6]
|
||
ldr sp, [r6] /* get new task's stack pointer */
|
||
/* »ñµÃÇл»µ½Ï̵߳ÄÕ» */
|
||
|
||
ldmfd sp!, {r4} /* pop new task's spsr */
|
||
/* »Ö¸´SPSR */
|
||
msr SPSR_cxsf, r4
|
||
ldmfd sp!, {r4} /* pop new task's psr */
|
||
/* »Ö¸´CPSR */
|
||
msr CPSR_cxsf, r4
|
||
|
||
ldmfd sp!, {r0-r12,lr,pc} /* pop new task's r0-r12,lr & pc */
|
||
/* »Ö¸´R0 ¨C R12£¬LR¼°PC¼Ä´æÆ÷ */
|
||
|
||
/* ´úÂë¼ÓÃܹ¦ÄÜ */
|
||
#if defined(CODE_PROTECTION)
|
||
.org 0x01FC
|
||
.word 0x87654321
|
||
#endif
|
||
|