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