xref: /nrf52832-nimble/rt-thread/libcpu/arm/AT91SAM7S/context_rvds.S (revision 104654410c56c573564690304ae786df310c91fc)
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 * 2009-01-20     Bernard      first version
9 */
10
11NOINT	EQU		0xc0	; disable interrupt in psr
12
13    AREA |.text|, CODE, READONLY, ALIGN=2
14    ARM
15    REQUIRE8
16    PRESERVE8
17
18;/*
19; * rt_base_t rt_hw_interrupt_disable();
20; */
21rt_hw_interrupt_disable	PROC
22    EXPORT rt_hw_interrupt_disable
23    MRS r0, cpsr
24    ORR r1, r0, #NOINT
25    MSR cpsr_c, r1
26    BX	lr
27    ENDP
28
29;/*
30; * void rt_hw_interrupt_enable(rt_base_t level);
31; */
32rt_hw_interrupt_enable	PROC
33    EXPORT rt_hw_interrupt_enable
34    MSR cpsr_c, r0
35    BX	lr
36    ENDP
37
38;/*
39; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
40; * r0 --> from
41; * r1 --> to
42; */
43rt_hw_context_switch	PROC
44    EXPORT rt_hw_context_switch
45    STMFD	sp!, {lr}			; push pc (lr should be pushed in place of PC)
46    STMFD	sp!, {r0-r12, lr}	; push lr & register file
47
48    MRS		r4, cpsr
49    STMFD	sp!, {r4}			; push cpsr
50    MRS		r4, spsr
51    STMFD	sp!, {r4}			; push spsr
52
53    STR	sp, [r0]				; store sp in preempted tasks TCB
54    LDR	sp, [r1]				; get new task stack pointer
55
56    LDMFD	sp!, {r4}			; pop new task spsr
57    MSR	spsr_cxsf, r4
58    LDMFD	sp!, {r4}			; pop new task cpsr
59    MSR	cpsr_cxsf, r4
60
61    LDMFD	sp!, {r0-r12, lr, pc}	; pop new task r0-r12, lr & pc
62    ENDP
63
64;/*
65; * void rt_hw_context_switch_to(rt_uint32 to);
66; * r0 --> to
67; */
68rt_hw_context_switch_to	PROC
69    EXPORT rt_hw_context_switch_to
70    LDR	sp, [r0]				; get new task stack pointer
71
72    LDMFD	sp!, {r4}			; pop new task spsr
73    MSR	spsr_cxsf, r4
74    LDMFD	sp!, {r4}			; pop new task cpsr
75    MSR	cpsr_cxsf, r4
76
77    LDMFD	sp!, {r0-r12, lr, pc}	; pop new task r0-r12, lr & pc
78    ENDP
79
80;/*
81; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
82; */
83    IMPORT rt_thread_switch_interrupt_flag
84    IMPORT rt_interrupt_from_thread
85    IMPORT rt_interrupt_to_thread
86
87rt_hw_context_switch_interrupt	PROC
88    EXPORT rt_hw_context_switch_interrupt
89    LDR r2, =rt_thread_switch_interrupt_flag
90    LDR r3, [r2]
91    CMP r3, #1
92    BEQ _reswitch
93    MOV r3, #1							; set rt_thread_switch_interrupt_flag to 1
94    STR r3, [r2]
95    LDR r2, =rt_interrupt_from_thread	; set rt_interrupt_from_thread
96    STR r0, [r2]
97_reswitch
98    LDR r2, =rt_interrupt_to_thread		; set rt_interrupt_to_thread
99    STR r1, [r2]
100    BX	lr
101    ENDP
102
103    END