xref: /nrf52832-nimble/rt-thread/libcpu/arm/AT91SAM7S/context_gcc.S (revision 042d53a763ad75cb1465103098bb88c245d95138)
1/*
2 * Copyright (c) 2006-2018, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date           Author       Notes
8 * 2006-03-13     Bernard      first version
9 */
10
11#define NOINT			0xc0
12
13/*
14 * rt_base_t rt_hw_interrupt_disable()/*
15 */
16.globl rt_hw_interrupt_disable
17rt_hw_interrupt_disable:
18	mrs r0, cpsr
19	orr r1, r0, #NOINT
20	msr cpsr_c, r1
21	mov pc, lr
22
23/*
24 * void rt_hw_interrupt_enable(rt_base_t level)/*
25 */
26.globl rt_hw_interrupt_enable
27rt_hw_interrupt_enable:
28	msr cpsr, r0
29	mov pc, lr
30
31/*
32 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)/*
33 * r0 --> from
34 * r1 --> to
35 */
36.globl rt_hw_context_switch
37rt_hw_context_switch:
38	stmfd	sp!, {lr}			/* push pc (lr should be pushed in place of PC) */
39	stmfd	sp!, {r0-r12, lr}	/* push lr & register file */
40
41	mrs		r4, cpsr
42	stmfd	sp!, {r4}			/* push cpsr */
43	mrs		r4, spsr
44	stmfd	sp!, {r4}			/* push spsr */
45
46	str		sp, [r0]			/* store sp in preempted tasks TCB */
47	ldr		sp, [r1]			/* get new task stack pointer */
48
49	ldmfd	sp!, {r4}			/* pop new task spsr */
50	msr		spsr_cxsf, r4
51	ldmfd	sp!, {r4}			/* pop new task cpsr */
52	msr		cpsr_cxsf, r4
53
54	ldmfd	sp!, {r0-r12, lr, pc}	/* pop new task r0-r12, lr & pc */
55
56/*
57 * void rt_hw_context_switch_to(rt_uint32 to)/*
58 * r0 --> to
59 */
60.globl rt_hw_context_switch_to
61rt_hw_context_switch_to:
62	ldr		sp, [r0]			/* get new task stack pointer */
63
64	ldmfd	sp!, {r4}			/* pop new task spsr */
65	msr		spsr_cxsf, r4
66	ldmfd	sp!, {r4}			/* pop new task cpsr */
67	msr		cpsr_cxsf, r4
68
69	ldmfd	sp!, {r0-r12, lr, pc}	/* pop new task r0-r12, lr & pc */
70
71/*
72 * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
73 */
74.globl rt_thread_switch_interrupt_flag
75.globl rt_interrupt_from_thread
76.globl rt_interrupt_to_thread
77.globl rt_hw_context_switch_interrupt
78rt_hw_context_switch_interrupt:
79	ldr		r2, =rt_thread_switch_interrupt_flag
80	ldr		r3, [r2]
81	cmp		r3, #1
82	beq		_reswitch
83	mov		r3, #1							/* set rt_thread_switch_interrupt_flag to 1 */
84	str		r3, [r2]
85	ldr		r2, =rt_interrupt_from_thread	/* set rt_interrupt_from_thread */
86	str		r0, [r2]
87_reswitch:
88	ldr		r2, =rt_interrupt_to_thread		/* set rt_interrupt_to_thread */
89	str		r1, [r2]
90	mov		pc, lr
91