diff options
| author | zchong_cht <[email protected]> | 2015-11-11 23:44:05 +0800 |
|---|---|---|
| committer | zchong_cht <[email protected]> | 2015-11-11 23:44:05 +0800 |
| commit | 3983f39f34e8fb8c1908aef86168268438c0aed0 (patch) | |
| tree | 2a84540adf84eeb913e1243fcb7f93411174f092 /libcpu/arm | |
| parent | 46fe0a48dc24ef6c696db2d80f910c5a482057f5 (diff) | |
Add iar compiler support for am335x.
Diffstat (limited to 'libcpu/arm')
| -rw-r--r-- | libcpu/arm/am335x/cp15_iar.s | 154 | ||||
| -rw-r--r-- | libcpu/arm/am335x/cpu.c | 3 | ||||
| -rw-r--r-- | libcpu/arm/am335x/interrupt.c | 14 | ||||
| -rw-r--r-- | libcpu/arm/am335x/start_iar.s | 292 |
4 files changed, 462 insertions, 1 deletions
diff --git a/libcpu/arm/am335x/cp15_iar.s b/libcpu/arm/am335x/cp15_iar.s new file mode 100644 index 0000000000..ae59ed04dc --- /dev/null +++ b/libcpu/arm/am335x/cp15_iar.s @@ -0,0 +1,154 @@ +/* + * File : cp15_iar.s + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2015, RT-Thread Development Team + * http://www.rt-thread.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-04-06 zchong change to iar compiler from convert from cp15_gcc.S + */ + + SECTION .text:CODE:NOROOT(2) + + ARM + + EXPORT rt_cpu_vector_set_base +rt_cpu_vector_set_base: + MCR p15, #0, r0, c12, c0, #0 + DSB + BX lr + + EXPORT rt_cpu_vector_get_base +rt_cpu_vector_get_base: + MRC p15, #0, r0, c12, c0, #0 + BX lr + + EXPORT rt_cpu_get_sctlr +rt_cpu_get_sctlr: + MRC p15, #0, r0, c1, c0, #0 + BX lr + + EXPORT rt_cpu_dcache_enable +rt_cpu_dcache_enable: + MRC p15, #0, r0, c1, c0, #0 + ORR r0, r0, #0x00000004 + MCR p15, #0, r0, c1, c0, #0 + BX lr + + EXPORT rt_cpu_icache_enable +rt_cpu_icache_enable: + MRC p15, #0, r0, c1, c0, #0 + ORR r0, r0, #0x00001000 + MCR p15, #0, r0, c1, c0, #0 + BX lr + +;_FLD_MAX_WAY DEFINE 0x3ff +;_FLD_MAX_IDX DEFINE 0x7ff + + + EXPORT rt_cpu_dcache_clean_flush +rt_cpu_dcache_clean_flush: + PUSH {r4-r11} + DMB + MRC p15, #1, r0, c0, c0, #1 ; read clid register + ANDS r3, r0, #0x7000000 ; get level of coherency + MOV r3, r3, lsr #23 + BEQ finished + MOV r10, #0 +loop1: + ADD r2, r10, r10, lsr #1 + MOV r1, r0, lsr r2 + AND r1, r1, #7 + CMP r1, #2 + BLT skip + MCR p15, #2, r10, c0, c0, #0 + ISB + MRC p15, #1, r1, c0, c0, #0 + AND r2, r1, #7 + ADD r2, r2, #4 + ;LDR r4, _FLD_MAX_WAY + LDR r4, =0x3FF + ANDS r4, r4, r1, lsr #3 + CLZ r5, r4 + ;LDR r7, _FLD_MAX_IDX + LDR r7, =0x7FF + ANDS r7, r7, r1, lsr #13 +loop2: + MOV r9, r4 +loop3: + ORR r11, r10, r9, lsl r5 + ORR r11, r11, r7, lsl r2 + MCR p15, #0, r11, c7, c14, #2 + SUBS r9, r9, #1 + BGE loop3 + SUBS r7, r7, #1 + BGE loop2 +skip: + ADD r10, r10, #2 + CMP r3, r10 + BGT loop1 + +finished: + DSB + ISB + POP {r4-r11} + BX lr + + + EXPORT rt_cpu_dcache_disable +rt_cpu_dcache_disable: + PUSH {r4-r11, lr} + MRC p15, #0, r0, c1, c0, #0 + BIC r0, r0, #0x00000004 + MCR p15, #0, r0, c1, c0, #0 + BL rt_cpu_dcache_clean_flush + POP {r4-r11, lr} + BX lr + + + EXPORT rt_cpu_icache_disable +rt_cpu_icache_disable: + MRC p15, #0, r0, c1, c0, #0 + BIC r0, r0, #0x00001000 + MCR p15, #0, r0, c1, c0, #0 + BX lr + + EXPORT rt_cpu_mmu_disable +rt_cpu_mmu_disable: + MCR p15, #0, r0, c8, c7, #0 ; invalidate tlb + MRC p15, #0, r0, c1, c0, #0 + BIC r0, r0, #1 + MCR p15, #0, r0, c1, c0, #0 ; clear mmu bit + DSB + BX lr + + EXPORT rt_cpu_mmu_enable +rt_cpu_mmu_enable: + MRC p15, #0, r0, c1, c0, #0 + ORR r0, r0, #0x001 + MCR p15, #0, r0, c1, c0, #0 ; set mmu enable bit + DSB + BX lr + + EXPORT rt_cpu_tlb_set +rt_cpu_tlb_set: + MCR p15, #0, r0, c2, c0, #0 + DMB + BX lr + + END diff --git a/libcpu/arm/am335x/cpu.c b/libcpu/arm/am335x/cpu.c index e67983eed0..d75600711f 100644 --- a/libcpu/arm/am335x/cpu.c +++ b/libcpu/arm/am335x/cpu.c @@ -92,6 +92,8 @@ rt_inline void cache_disable(rt_uint32_t bit) } #endif + +#if defined(__CC_ARM)|(__GNUC__) /** * enable I-Cache * @@ -145,6 +147,7 @@ rt_base_t rt_hw_cpu_dcache_status() { return (cp15_rd() & DCACHE_MASK); } +#endif /** * shutdown CPU diff --git a/libcpu/arm/am335x/interrupt.c b/libcpu/arm/am335x/interrupt.c index 081bdd6b41..a13d089a7f 100644 --- a/libcpu/arm/am335x/interrupt.c +++ b/libcpu/arm/am335x/interrupt.c @@ -10,6 +10,7 @@ * Change Logs: * Date Author Notes * 2013-07-06 Bernard first version + * 2015-11-06 zchong support iar compiler */ #include <rthw.h> @@ -53,13 +54,22 @@ void rt_dump_aintc(void) const unsigned int AM335X_VECTOR_BASE = 0x4030FC00; extern void rt_cpu_vector_set_base(unsigned int addr); +#ifdef __ICCARM__ +extern int __vector; +#else extern int system_vectors; +#endif static void rt_hw_vector_init(void) { unsigned int *dest = (unsigned int *)AM335X_VECTOR_BASE; + +#ifdef __ICCARM__ + unsigned int *src = (unsigned int *)&__vector; +#else unsigned int *src = (unsigned int *)&system_vectors; - +#endif + rt_memcpy(dest, src, 16 * 4); rt_cpu_vector_set_base(AM335X_VECTOR_BASE); } @@ -203,3 +213,5 @@ void rt_dump_isr_table(void) } } /*@}*/ + + diff --git a/libcpu/arm/am335x/start_iar.s b/libcpu/arm/am335x/start_iar.s new file mode 100644 index 0000000000..61f977f2c6 --- /dev/null +++ b/libcpu/arm/am335x/start_iar.s @@ -0,0 +1,292 @@ +/* + * File : start_iar.s + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2015, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-04-06 zchong the first version + */ + + MODULE ?cstartup + + ; -------------------- +; Mode, correspords to bits 0-5 in CPSR + +MODE_MSK DEFINE 0x1F ; Bit mask for mode bits in CPSR +I_Bit DEFINE 0x80 ; when I bit is set, IRQ is disabled +F_Bit DEFINE 0x40 ; when F bit is set, FIQ is disabled + +USR_MODE DEFINE 0x10 ; User mode +FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode +IRQ_MODE DEFINE 0x12 ; Interrupt Request mode +SVC_MODE DEFINE 0x13 ; Supervisor mode +ABT_MODE DEFINE 0x17 ; Abort mode +UND_MODE DEFINE 0x1B ; Undefined Instruction mode +SYS_MODE DEFINE 0x1F ; System mode + + + ;; Forward declaration of sections. + SECTION IRQ_STACK:DATA:NOROOT(3) + SECTION FIQ_STACK:DATA:NOROOT(3) + SECTION SVC_STACK:DATA:NOROOT(3) + SECTION ABT_STACK:DATA:NOROOT(3) + SECTION UND_STACK:DATA:NOROOT(3) + SECTION CSTACK:DATA:NOROOT(3) + SECTION .text:CODE + + + SECTION .intvec:CODE:NOROOT(5) + + PUBLIC __vector + PUBLIC __iar_program_start + + +__iar_init$$done: ; The vector table is not needed + ; until after copy initialization is done + +__vector: ; Make this a DATA label, so that stack usage + ; analysis doesn't consider it an uncalled fun + ARM + + ; All default exception handlers (except reset) are + ; defined as weak symbol definitions. + ; If a handler is defined by the application it will take precedence. + LDR PC,Reset_Addr ; Reset + LDR PC,Undefined_Addr ; Undefined instructions + LDR PC,SWI_Addr ; Software interrupt (SWI/SVC) + LDR PC,Prefetch_Addr ; Prefetch abort + LDR PC,Abort_Addr ; Data abort + DCD 0 ; RESERVED + LDR PC,IRQ_Addr ; IRQ + LDR PC,FIQ_Addr ; FIQ + + DATA + +Reset_Addr: DCD __iar_program_start +Undefined_Addr: DCD Undefined_Handler +SWI_Addr: DCD SWI_Handler +Prefetch_Addr: DCD Prefetch_Handler +Abort_Addr: DCD Abort_Handler +IRQ_Addr: DCD IRQ_Handler +FIQ_Addr: DCD FIQ_Handler + + +; -------------------------------------------------- +; ?cstartup -- low-level system initialization code. +; +; After a reset execution starts here, the mode is ARM, supervisor +; with interrupts disabled. +; + + SECTION .text:CODE:NOROOT(2) + + EXTERN rt_hw_trap_udef + EXTERN rt_hw_trap_swi + EXTERN rt_hw_trap_pabt + EXTERN rt_hw_trap_dabt + EXTERN rt_hw_trap_fiq + EXTERN rt_hw_trap_irq + 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_current_thread + EXTERN vmm_thread + EXTERN vmm_virq_check + + EXTERN __cmain + REQUIRE __vector + EXTWEAK __iar_init_core + EXTWEAK __iar_init_vfp + + + ARM + +__iar_program_start: +?cstartup: + +; +; Add initialization needed before setup of stackpointers here. +; + +; +; Initialize the stack pointers. +; The pattern below can be used for any of the exception stacks: +; FIQ, IRQ, SVC, ABT, UND, SYS. +; The USR mode uses the same stack as SYS. +; The stack segments must be defined in the linker command file, +; and be declared above. +; + + MRS r0, cpsr ; Original PSR value + + ;; Set up the interrupt stack pointer. + BIC r0, r0, #MODE_MSK ; Clear the mode bits + ORR r0, r0, #IRQ_MODE ; Set IRQ mode bits + MSR cpsr_c, r0 ; Change the mode + LDR sp, =SFE(IRQ_STACK) ; End of IRQ_STACK + BIC sp,sp,#0x7 ; Make sure SP is 8 aligned + + ;; Set up the fast interrupt stack pointer. + BIC r0, r0, #MODE_MSK ; Clear the mode bits + ORR r0, r0, #FIQ_MODE ; Set FIR mode bits + MSR cpsr_c, r0 ; Change the mode + LDR sp, =SFE(FIQ_STACK) ; End of FIQ_STACK + BIC sp,sp,#0x7 ; Make sure SP is 8 aligned + + BIC r0,r0,#MODE_MSK ; Clear the mode bits + ORR r0,r0,#ABT_MODE ; Set Abort mode bits + MSR cpsr_c,r0 ; Change the mode + LDR sp,=SFE(ABT_STACK) ; End of ABT_STACK + BIC sp,sp,#0x7 ; Make sure SP is 8 aligned + + BIC r0,r0,#MODE_MSK ; Clear the mode bits + ORR r0,r0,#UND_MODE ; Set Undefined mode bits + MSR cpsr_c,r0 ; Change the mode + LDR sp,=SFE(UND_STACK) ; End of UND_STACK + BIC sp,sp,#0x7 ; Make sure SP is 8 aligned + + ;; Set up the normal stack pointer. + BIC r0 ,r0, #MODE_MSK ; Clear the mode bits + ORR r0 ,r0, #SVC_MODE ; Set System mode bits + MSR cpsr_c, r0 ; Change the mode + LDR sp, =SFE(SVC_STACK) ; End of SVC_STACK + BIC sp,sp,#0x7 ; Make sure SP is 8 aligned + + ;; Turn on core features assumed to be enabled. + BL __iar_init_core + + ;; Initialize VFP (if needed). + BL __iar_init_vfp + + + ;; Continue to __cmain for C-level initialization. + B __cmain + + +Undefined_Handler: + SUB sp, sp, #72 + STMIA sp, {r0 - r12} ;/* Calling r0-r12 */ + ADD r8, sp, #60 + + MRS r1, cpsr + MRS r2, spsr + ORR r2,r2, #I_Bit | F_Bit + MSR cpsr_c, r2 + MOV r0, r0 + STMDB r8, {sp, lr} ;/* Calling SP, LR */ + MSR cpsr_c, r1 ;/* return to Undefined Instruction mode */ + + STR lr, [r8, #0] ;/* Save calling PC */ + MRS r6, spsr + STR r6, [r8, #4] ;/* Save CPSR */ + STR r0, [r8, #8] ;/* Save OLD_R0 */ + MOV r0, sp + + BL rt_hw_trap_udef + + LDMIA sp, {r0 - r12} ;/* Calling r0 - r2 */ + MOV r0, r0 + LDR lr, [sp, #60] ;/* Get PC */ + ADD sp, sp, #72 + MOVS pc, lr ;/* return & move spsr_svc into cpsr */ + +SWI_Handler: + BL rt_hw_trap_swi + +Prefetch_Handler: + BL rt_hw_trap_pabt + +Abort_Handler: + SUB sp, sp, #72 + STMIA sp, {r0 - r12} ;/* Calling r0-r12 */ + ADD r8, sp, #60 + STMDB r8, {sp, lr} ;/* Calling SP, LR */ + STR lr, [r8, #0] ;/* Save calling PC */ + MRS r6, spsr + STR r6, [r8, #4] ;/* Save CPSR */ + STR r0, [r8, #8] ;/* Save OLD_R0 */ + MOV r0, sp + + BL rt_hw_trap_dabt + + LDMIA sp, {r0 - r12} ;/* Calling r0 - r2 */ + MOV r0, r0 + LDR lr, [sp, #60] ;/* Get PC */ + ADD sp, sp, #72 + MOVS pc, lr ;/* return & move spsr_svc into cpsr */ + +FIQ_Handler: + STMFD sp!,{r0-r7,lr} + BL rt_hw_trap_fiq + LDMFD sp!,{r0-r7,lr} + SUBS pc,lr,#4 + +IRQ_Handler: + STMFD sp!, {r0-r12,lr} + + BL rt_interrupt_enter + BL rt_hw_trap_irq + BL rt_interrupt_leave + + ; if rt_thread_switch_interrupt_flag set, jump to + ; rt_hw_context_switch_interrupt_do and don't return + 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 ; clear flag + STR r1, [r0] + + LDMFD sp!, {r0-r12,lr}; reload saved registers + STMFD sp, {r0-r2} ; save r0-r2 + + MRS r0, spsr ; get cpsr of interrupt thread + + SUB r1, sp, #4*3 + SUB r2, lr, #4 ; save old task's pc to r2 + + ; switch to SVC mode with no interrupt + MSR cpsr_c, #I_Bit | F_Bit | SVC_MODE + + STMFD sp!, {r2} ; push old task's pc + STMFD sp!, {r3-r12,lr}; push old task's lr,r12-r4 + LDMFD r1, {r1-r3} ; restore r0-r2 of the interrupt thread + STMFD sp!, {r1-r3} ; push old task's r0-r2 + STMFD sp!, {r0} ; push old task's cpsr + + LDR r4, =rt_interrupt_from_thread + LDR r5, [r4] + STR sp, [r5] ; store sp in preempted tasks's TCB + + 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 cpsr to spsr + MSR spsr_cxsf, r4 + + LDMFD sp!, {r0-r12,lr,pc}^ ; pop new task's r0-r12,lr & pc, copy spsr to cpsr + + END |
