summaryrefslogtreecommitdiff
path: root/libcpu/arm/am335x
diff options
context:
space:
mode:
authorzchong_cht <[email protected]>2015-11-11 23:44:05 +0800
committerzchong_cht <[email protected]>2015-11-11 23:44:05 +0800
commit3983f39f34e8fb8c1908aef86168268438c0aed0 (patch)
tree2a84540adf84eeb913e1243fcb7f93411174f092 /libcpu/arm/am335x
parent46fe0a48dc24ef6c696db2d80f910c5a482057f5 (diff)
Add iar compiler support for am335x.
Diffstat (limited to 'libcpu/arm/am335x')
-rw-r--r--libcpu/arm/am335x/cp15_iar.s154
-rw-r--r--libcpu/arm/am335x/cpu.c3
-rw-r--r--libcpu/arm/am335x/interrupt.c14
-rw-r--r--libcpu/arm/am335x/start_iar.s292
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