Refactor to use new protocol module and sipo.
[bertos.git] / bertos / cpu / avr / hw / switch_ctx_avr.S
1 /*!
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2004, 2008 Develer S.r.l. (http://www.develer.com/)
30  * Copyright 1999, 2000, 2001 Bernie Innocenti <bernie@codewiz.org>
31  * -->
32  *
33  * \author Bernie Innocenti <bernie@codewiz.org>
34  * \author Stefano Fedrigo <aleph@develer.com>
35  *
36  * \brief AVR context switch
37  *
38  */
39
40 #include <avr/io.h>
41
42 /* void asm_switch_context(void **new_sp [r24:r25], void **save_sp [r22:r23]) */
43 .globl asm_switch_context
44 asm_switch_context:
45
46 ;       r0 is the TEMP REG and can be used freely.
47 ;       r1 is the ZERO REG and must always contain 0.
48 ;
49 ;       Stack frame is 18 byte, remember to update
50 ;       CPU_SAVED_REGS_CNT if you change pushed regs.
51
52         push    r2
53         push    r3
54         push    r4
55         push    r5
56         push    r6
57         push    r7
58         push    r8
59         push    r9
60         push    r10
61         push    r11
62         push    r12
63         push    r13
64         push    r14
65         push    r15
66         push    r16
67         push    r17
68
69         push    r28
70         push    r29
71
72         in      r18,SPL-__SFR_OFFSET    ; r18:r19 = SP
73         in      r19,SPH-__SFR_OFFSET
74         movw    r26,r22                 ; X = save_sp
75         st      X+,r18                  ; *save_sp = SP
76         st      X,r19
77         movw    r26,r24                 ; X = new_sp
78         ld      r18,X+
79         ld      r19,X
80
81 ;FIXME: We probably need to safe the RAMP registers for some XMEGA devices / setups
82
83 ;       Set new stack pointer.
84 ;       AVR is an 8 bit processor so
85 ;       care must be taken when updating
86 ;       SP that is a 16 bit reg.
87 ;       Two instructions are required to update SP
88 ;       so an IRQ can sneak in between them.
89 ;       So IRQ *MUST* be disabled and then restored.
90         in      r0, SREG-__SFR_OFFSET
91         cli                             ; Disable interrupt
92         out     SPL-__SFR_OFFSET,r18    ; SP = *new_sp
93         out     SPH-__SFR_OFFSET,r19
94         out     SREG-__SFR_OFFSET,r0    ; Restore previous IRQ state
95
96         pop     r29
97         pop     r28
98
99         pop     r17
100         pop     r16
101         pop     r15
102         pop     r14
103         pop     r13
104         pop     r12
105         pop     r11
106         pop     r10
107         pop     r9
108         pop     r8
109         pop     r7
110         pop     r6
111         pop     r5
112         pop     r4
113         pop     r3
114         pop     r2
115
116         ret