xref: /nrf52832-nimble/rt-thread/libcpu/arm/lpc214x/context_gcc.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 */
9.global rt_hw_interrupt_disable
10.global rt_hw_interrupt_enable
11.global rt_hw_context_switch
12.global rt_hw_context_switch_to
13.global rt_hw_context_switch_interrupt
14
15.equ  NOINT, 0xc0
16
17/*
18 * rt_base_t rt_hw_interrupt_disable();
19 关闭中断,关闭前返回CPSR寄存器值
20 */
21rt_hw_interrupt_disable:
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  恢复中断状态
32 */
33rt_hw_interrupt_enable:
34	//EXPORT rt_hw_interrupt_enable
35	MSR cpsr_c, r0
36	BX	lr
37	//ENDP
38
39/*
40 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
41 * r0 --> from
42 * r1 --> to
43 进行线程的上下文切换
44 */
45rt_hw_context_switch:
46	//EXPORT rt_hw_context_switch
47	STMFD	sp!, {lr}			/* push pc (lr should be pushed in place of PC) */
48							    /* 把LR寄存器压入栈(这个函数返回后的下一个执行处) */
49	STMFD	sp!, {r0-r12, lr}	/* push lr & register file */
50								/*  把R0 – R12以及LR压入栈 */
51
52	MRS		r4, cpsr			/*  读取CPSR寄存器到R4寄存器 */
53	STMFD	sp!, {r4}			/* push cpsr */
54							    /* 把R4寄存器压栈(即上一指令取出的CPSR寄存器) */
55	MRS		r4, spsr		    /* 读取SPSR寄存器到R4寄存器 */
56	STMFD	sp!, {r4}			/* push spsr */
57								/* 把R4寄存器压栈(即SPSR寄存器) */
58
59	STR	sp, [r0]				/* store sp in preempted tasks TCB */
60								/*  把栈指针更新到TCB的sp,是由R0传入此函数 */
61								/*  到这里换出线程的上下文都保存在栈中 */
62	LDR	sp, [r1]				/* get new task stack pointer */
63								/*  载入切换到线程的TCB的sp */
64								/*  从切换到线程的栈中恢复上下文,次序和保存的时候刚好相反 */
65
66	LDMFD	sp!, {r4}			/* pop new task spsr */
67								/* 出栈到R4寄存器(保存了SPSR寄存器) */
68	MSR	spsr_cxsf, r4			/* 恢复SPSR寄存器 */
69	LDMFD	sp!, {r4}			/* pop new task cpsr */
70								/* 出栈到R4寄存器(保存了CPSR寄存器) */
71	MSR	cpsr_cxsf, r4			/*  恢复CPSR寄存器 */
72
73	LDMFD	sp!, {r0-r12, lr, pc}	/* pop new task r0-r12, lr & pc */
74									/* 对R0 – R12及LR、PC进行恢复 */
75	//ENDP
76
77rt_hw_context_switch_to:
78	//EXPORT rt_hw_context_switch_to
79	LDR	sp, [r0]				/* get new task stack pointer */
80								/* 获得切换到线程的SP指针 */
81
82	LDMFD	sp!, {r4}			/* pop new task spsr */
83								/* 出栈R4寄存器(保存了SPSR寄存器值) */
84	MSR	spsr_cxsf, r4			/* 恢复SPSR寄存器 */
85	LDMFD	sp!, {r4}			/* pop new task cpsr */
86								/* 出栈R4寄存器(保存了CPSR寄存器值) */
87	MSR	cpsr_cxsf, r4			/* 恢复CPSR寄存器 */
88
89	LDMFD	sp!, {r0-r12, lr, pc}	/* pop new task r0-r12, lr & pc */
90									/* 恢复R0 – R12,LR及PC寄存器 */
91	//ENDP
92
93rt_hw_context_switch_interrupt:
94	//EXPORT rt_hw_context_switch_interrupt
95	LDR r2, =rt_thread_switch_interrupt_flag
96	LDR r3, [r2]						/* 载入中断中切换标致地址 */
97	CMP r3, #1							/* 等于 1 ?*/
98	BEQ _reswitch						/* 如果等于1,跳转到_reswitch*/
99	MOV r3, #1							/* set rt_thread_switch_interrupt_flag to 1*/
100										/* 设置中断中切换标志位1 */
101	STR r3, [r2]						/* */
102	LDR r2, =rt_interrupt_from_thread	/* set rt_interrupt_from_thread*/
103	STR r0, [r2]						/* 保存切换出线程栈指针*/
104_reswitch:
105	LDR r2, =rt_interrupt_to_thread		/* set rt_interrupt_to_thread*/
106	STR r1, [r2]						/* 保存切换到线程栈指针*/
107	BX	lr
108	//ENDP
109
110	//END