xref: /nrf52832-nimble/rt-thread/libcpu/xilinx/microblaze/context_gcc.S (revision 104654410c56c573564690304ae786df310c91fc)
1/*
2 * File      : context_gcc.S
3 * This file is part of RT-Thread RTOS
4 * COPYRIGHT (C) 2006, RT-Thread Development Team
5 *
6 * The license and distribution terms for this file may be
7 * found in the file LICENSE in this distribution or at
8 * http://www.rt-thread.org/license/LICENSE
9 *
10 * Change Logs:
11 * Date           Author       Notes
12 * 2011-12-17     nl1031       first implementation for MicroBlaze.
13 *
14 */
15
16#include "microblaze.inc"
17
18	.text
19    	.globl	rt_interrupt_enter
20    	.globl	rt_interrupt_leave
21
22/*
23 * rt_base_t rt_hw_interrupt_disable()
24 * copy from ucos-ii
25 */
26
27	.globl	rt_hw_interrupt_disable
28	.ent	rt_hw_interrupt_disable
29	.align	2
30rt_hw_interrupt_disable:
31    	ADDIK   r1, r1, -4
32    	SW      r4, r1, r0
33
34    	MFS     r3, RMSR
35    	ANDNI   r4, r3, IE_BIT
36    	MTS     RMSR, r4
37
38    	LW      r4, r1, r0
39    	ADDIK   r1, r1, 4
40
41    	AND     r0, r0, r0             /* NO-OP - pipeline flush                             */
42    	AND     r0, r0, r0             /* NO-OP - pipeline flush                             */
43    	AND     r0, r0, r0             /* NO-OP - pipeline flush                             */
44
45    	RTSD    r15, 8
46    	AND     r0, r0, r0
47	.end	rt_hw_interrupt_disable
48
49/*
50 * void rt_hw_interrupt_enable(rt_base_t level)
51 * copy from ucos-ii
52 */
53	.globl	rt_hw_interrupt_enable
54	.ent	rt_hw_interrupt_enable
55	.align	2
56rt_hw_interrupt_enable:
57    	RTSD    r15, 8
58    	MTS     rMSR, r5               		/* Move the saved status from r5 into rMSR            */
59	.end	rt_hw_interrupt_enable
60
61/*
62 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
63 * r5 --> from
64 * r6 --> to
65 */
66
67	.globl rt_interrupt_from_thread
68	.globl rt_interrupt_to_thread
69	.globl rt_hw_context_switch
70	.ent rt_hw_context_switch
71	.align	2
72rt_hw_context_switch:
73	PUSH_ALL
74    	MFS     r3,  RMSR                   /* save the MSR */
75    	SWI     r3,  r1, STACK_RMSR
76	SWI		r1,  r5, 0					/* store sp in preempted tasks TCB */
77	LWI		r1,  r6, 0					/* get new task stack pointer */
78
79    	LWI     r3,  r1, STACK_RMSR
80    	ANDI    r3,  r3, IE_BIT
81    	BNEI    r3,  rt_hw_context_switch_ie /*if IE bit set,should be use RTID (return from interrupt). */
82
83    	LWI     r3,  r1, STACK_RMSR
84    	MTS     RMSR,r3
85	POP_ALL
86    	ADDIK   r1,  r1, STACK_SIZE
87    	RTSD    r15, 8
88    	AND     r0,  r0, r0
89
90rt_hw_context_switch_ie:
91
92    	LWI     r3,  r1, STACK_RMSR
93    	ANDNI   r3,  r3, IE_BIT         	/* clear IE bit, prevent interrupt occur immediately*/
94    	MTS     RMSR,r3
95    	LWI     r3,  r1, STACK_R03
96	POP_ALL
97    	ADDIK   r1,  r1, STACK_SIZE
98    	RTID    r14, 0                    	/* IE bit will be set automatically */
99    	AND     r0,  r0, r0
100	.end	rt_hw_context_switch
101
102/*
103 * void rt_hw_context_switch_to(rt_uint32 to)
104 * r5 --> to
105 */
106	.globl 	rt_hw_context_switch_to
107	.ent   	rt_hw_context_switch_to
108	.align	2
109rt_hw_context_switch_to:
110	LWI		r1,	 r5, 0 					/* get new task stack pointer */
111    	LWI     r3,  r1, STACK_RMSR
112    	ANDNI   r3,  r3, IE_BIT         	/* clear IE bit, prevent interrupt occur immediately*/
113    	MTS     RMSR,r3
114	POP_ALL
115    	ADDIK   r1,  r1, STACK_SIZE
116    	RTID    r14, 0                    	/* IE bit will be set automatically */
117    	AND     r0,  r0, r0
118
119	.end 	rt_hw_context_switch_to
120
121/*
122 * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)
123 */
124	.globl 	rt_thread_switch_interrupt_flag
125	.globl 	rt_hw_context_switch_interrupt
126	.ent rt_hw_context_switch_interrupt
127	.align	2
128rt_hw_context_switch_interrupt:
129	LA	r3,	r0, rt_thread_switch_interrupt_flag
130	LWI	r4, r3, 0					/* load rt_thread_switch_interrupt_flag into r4 */
131
132	ANDI	r4, r4, 1
133	BNEI	r4, _reswitch				/* if rt_thread_switch_interrupt_flag = 1 */
134
135	ADDIK	r4, r0, 1					/* set rt_thread_switch_interrupt_flag to 1 */
136	SWI	r4, r3, 0
137
138	LA	r3, r0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
139	SWI	r5, r3, 0 					/* rt_interrupt_from_thread = from */
140_reswitch:
141	LA	r3, r0, rt_interrupt_to_thread	/* set rt_interrupt_to_thread */
142	SWI	r6, r3, 0 					/* rt_interrupt_to_thread = to */
143    	RTSD    r15, 8
144    	AND     r0, r0, r0
145	.end rt_hw_context_switch_interrupt
146
147
148    .globl     	_interrupt_handler
149	.section .text
150	.align 	2
151	.ent _interrupt_handler
152	.type _interrupt_handler, @function
153
154_interrupt_handler:
155	PUSH_ALL
156    	MFS     r3,  RMSR
157    	ORI     r3,  r3, IE_BIT
158    	SWI     r3,  r1, STACK_RMSR         	/* push MSR    */
159
160    	BRLID   r15, rt_interrupt_enter
161    	AND     r0,  r0, r0
162
163    	BRLID   r15, rt_hw_trap_irq
164    	AND     r0,  r0, r0
165
166    	BRLID   r15, rt_interrupt_leave
167    	AND     r0,  r0, r0
168
169	/*
170	 * if rt_thread_switch_interrupt_flag set, jump to
171	 * rt_hw_context_switch_interrupt_do and don't return
172	 */
173	LA	r3,  r0, rt_thread_switch_interrupt_flag
174	LWI	r4,  r3, 0
175
176	ANDI	r4,  r4, 1
177	BNEI 	r4,  rt_hw_context_switch_interrupt_do
178
179    	LWI     r3,  r1, STACK_RMSR
180    	ANDNI   r3,  r3, IE_BIT
181    	MTS     RMSR,r3
182	POP_ALL
183    	ADDIK   r1,  r1, STACK_SIZE
184
185    	RTID    r14, 0
186    	AND     r0,  r0, r0
187
188/*
189 * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
190 */
191rt_hw_context_switch_interrupt_do:
192	SWI	r0,  r3, 0 						/* clear rt_thread_switch_interrupt_flag */
193
194	LA	r3,  r0, rt_interrupt_from_thread
195	LW	r4,  r0, r3
196	SWI	r1,  r4, 0						/* store sp in preempted tasks's TCB */
197
198	LA	r3,  r0, rt_interrupt_to_thread
199	LW	r4,  r0, r3
200	LWI	r1,  r4, 0						/* get new task's stack pointer */
201
202    	LWI     r3,  r1, STACK_RMSR
203    	ANDI    r3,  r3, IE_BIT
204    	BNEI    r3,  return_with_ie     	/*if IE bit set,should be use RTID (return from interrupt). */
205
206    	LWI     r3,  r1, STACK_RMSR
207    	MTS     RMSR,r3
208	POP_ALL
209    	ADDIK   r1,  r1, STACK_SIZE
210    	RTSD    r15, 8
211    	AND     r0,  r0, r0
212
213return_with_ie:
214
215    	LWI     r3,  r1, STACK_RMSR
216    	ANDNI   r3,  r3, IE_BIT         	/* clear IE bit, prevent interrupt occur immediately*/
217    	MTS     RMSR,r3
218    	LWI     r3,  r1, STACK_R03
219	POP_ALL
220    	ADDIK   r1,  r1, STACK_SIZE
221    	RTID    r14, 0                    	/* IE bit will be set automatically */
222    	AND     r0,  r0, r0
223
224.end _interrupt_handler
225
226