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