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