summaryrefslogtreecommitdiff
path: root/libcpu/arm/armv6/context_gcc.S
diff options
context:
space:
mode:
authorBernard Xiong <[email protected]>2016-04-18 13:52:39 +0800
committerBernard Xiong <[email protected]>2016-04-18 13:52:39 +0800
commit43f68131ce64fbb4c3e476e684f3d06919ebd5af (patch)
tree4bc755c1f350d2fbb30ae7c1c050be4d3d2125a5 /libcpu/arm/armv6/context_gcc.S
parent6d03ce9a7bfd4ff94665465d1c07f6c816fe19a2 (diff)
[BSP] Add fh8620 bsp from Shanghai Fullhan Microelectronics Co., Ltd.
FH8620 BSP Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd. All rights reserved
Diffstat (limited to 'libcpu/arm/armv6/context_gcc.S')
-rw-r--r--libcpu/arm/armv6/context_gcc.S122
1 files changed, 122 insertions, 0 deletions
diff --git a/libcpu/arm/armv6/context_gcc.S b/libcpu/arm/armv6/context_gcc.S
new file mode 100644
index 0000000000..87ba43ae52
--- /dev/null
+++ b/libcpu/arm/armv6/context_gcc.S
@@ -0,0 +1,122 @@
+/*
+ * File : context.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, 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
+ * 2011-01-13 weety copy from mini2440
+ */
+
+/*!
+ * \addtogroup ARMv6
+ */
+/*@{*/
+
+#include <rtconfig.h>
+
+#define NOINT 0xc0
+#define FPEXC_EN (1 << 30) /* VFP enable bit */
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+.globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+ mrs r0, cpsr
+ cpsid if
+ bx lr
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+.globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+ msr cpsr_c, r0
+ bx lr
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ */
+.globl rt_hw_context_switch
+rt_hw_context_switch:
+ stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC)
+ stmfd sp!, {r0-r12, lr} @ push lr & register file
+
+ mrs r4, cpsr
+ tst lr, #0x01
+ orrne r4, r4, #0x20 @ it's thumb code
+
+ stmfd sp!, {r4} @ push cpsr
+
+ str sp, [r0] @ store sp in preempted tasks TCB
+ ldr sp, [r1] @ get new task stack pointer
+
+ ldmfd sp!, {r4} @ pop new task cpsr to spsr
+ msr spsr_cxsf, r4
+#ifdef RT_USING_VFP
+ vmrs r0, fpexc
+ bic r0, r0, #FPEXC_EN @ always disable VFP so we can
+ @ lazily save/restore the old state.
+ vmsr fpexc, r0
+#endif
+_do_switch:
+ ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * r0 --> to
+ */
+.globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+ ldr sp, [r0] @ get new task stack pointer
+
+ ldmfd sp!, {r4} @ pop new task spsr
+ msr spsr_cxsf, r4
+
+ bic r4, r4, #0x20 @ must be ARM mode
+ msr cpsr_cxsf, r4
+#ifdef RT_USING_VFP
+ vmrs r0, fpexc
+ bic r0, r0, #FPEXC_EN @ always disable VFP so we can
+ @ lazily save/restore the old state.
+ vmsr fpexc, r0
+#endif
+ ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ */
+.globl rt_thread_switch_interrupt_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+.globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+ ldr r2, =rt_thread_switch_interrupt_flag
+ ldr r3, [r2]
+ cmp r3, #1
+ beq _reswitch
+ mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1
+ str r3, [r2]
+ ldr r2, =rt_interrupt_from_thread @ set rt_interrupt_from_thread
+ str r0, [r2]
+_reswitch:
+ ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread
+ str r1, [r2]
+ bx lr