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