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