xref: /nrf52832-nimble/rt-thread/libcpu/avr32/uc3/context_gcc.S (revision 042d53a763ad75cb1465103098bb88c245d95138)
1/*
2 * File      : context.S
3 * This file is part of RT-Thread RTOS
4 * COPYRIGHT (C) 2010, 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 * 2010-03-27     Kyle         First version
13 */
14
15#define AVR32_SR			0
16#define AVR32_SR_GM_OFFSET	16
17
18.text
19
20/*
21 * rt_base_t rt_hw_interrupt_disable()
22 */
23.globl rt_hw_interrupt_disable
24.type rt_hw_interrupt_disable, %function
25rt_hw_interrupt_disable:
26	ssrf	AVR32_SR_GM_OFFSET
27	mov		pc, lr
28
29/*
30 * void rt_hw_interrupt_enable(rt_base_t level)
31 */
32.globl rt_hw_interrupt_enable
33.type rt_hw_interrupt_enable, %function
34rt_hw_interrupt_enable:
35	csrf	AVR32_SR_GM_OFFSET
36	mov		pc, lr
37
38/*
39 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)/*
40 * r8 --> from
41 * r9 --> to
42 */
43.globl rt_hw_context_switch
44.type rt_hw_context_switch, %function
45rt_hw_context_switch:
46	ssrf	AVR32_SR_GM_OFFSET	/* Disable global interrupt */
47	stm		--sp, r8-r12, lr	/* Push R8-R12, LR */
48	st.w	--sp, lr			/* Push LR (instead of PC) */
49	mfsr	r8, AVR32_SR		/* Read Status Register */
50	cbr		r8, AVR32_SR_GM_OFFSET	/* Clear GM bit */
51	st.w	--sp, r8			/* Push SR */
52	stm		--sp, r0-r7			/* Push R0-R7 */
53								/* Stack layout: R8-R12, LR, PC, SR, R0-R7 */
54
55	st.w	r12[0], sp			/* Store SP in preempted tasks TCB */
56	ld.w	sp, r11[0]			/* Get new task stack pointer */
57
58	ldm		sp++, r0-r7			/* pop R0-R7 */
59	ld.w	r8, sp++			/* pop SR */
60	mtsr	AVR32_SR, r8		/* Restore SR */
61	ldm		sp++, r8-r12, lr, pc/* Pop R8-R12, LR, PC and resume to thread */
62
63/*
64 * void rt_hw_context_switch_to(rt_uint32 to)/*
65 * r0 --> to
66 */
67.globl rt_hw_context_switch_to
68.type rt_hw_context_switch_to, %function
69rt_hw_context_switch_to:
70	ld.w	sp, r12[0]			/* Get new task stack pointer */
71
72	ldm		sp++, r0-r7			/* pop R0-R7 */
73	ld.w	r8, sp++			/* pop SR */
74	mtsr	AVR32_SR, r8		/* Restore SR */
75	ldm		sp++, r8-r12, lr, pc/* Pop R8-R12, LR, PC and resume execution */
76
77/*
78 * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
79 */
80.globl rt_thread_switch_interrupt_flag
81.globl rt_interrupt_from_thread
82.globl rt_interrupt_to_thread
83.globl rt_hw_context_switch_interrupt
84.type rt_hw_context_switch_interrupt, %function
85rt_hw_context_switch_interrupt:
86	lda.w	r8, rt_thread_switch_interrupt_flag
87	ld.w	r9, r8[0]
88	cp.w	r9, 1
89	breq	_reswitch
90	mov		r9, 1
91	st.w	r8[0], r9
92	lda.w	r8, rt_interrupt_from_thread
93	st.w	r8[0], r12
94_reswitch:
95	lda.w	r8, rt_interrupt_to_thread
96	st.w	r8[0], r11
97	mov		pc, lr
98