Refactor switch context ASM files to comply to Wizard.
[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  * \version $Id$
34  * \author Bernie Innocenti <bernie@codewiz.org>
35  * \author Stefano Fedrigo <aleph@develer.com>
36  *
37  * \brief AVR context switch
38  *
39  */
40
41 #include <avr/io.h>
42
43 /* void asm_switch_context(void **new_sp [r24:r25], void **save_sp [r22:r23]) */
44 .globl asm_switch_context
45 asm_switch_context:
46
47 ;       r0 is the TEMP REG and can be used freely.
48 ;       r1 is the ZERO REG and must always contain 0.
49 ;
50 ;       Stack frame is 19 byte, remember to update
51 ;       CPU_SAVED_REGS_CNT if you change pushed regs.
52
53         in      r0,SREG-__SFR_OFFSET
54         push    r0
55 ;       push    r1      ;zero-reg
56         push    r2
57         push    r3
58         push    r4
59         push    r5
60         push    r6
61         push    r7
62         push    r8
63         push    r9
64         push    r10
65         push    r11
66         push    r12
67         push    r13
68         push    r14
69         push    r15
70         push    r16
71         push    r17
72 ;       push    r18     ;caller-save
73 ;       push    r19     ;caller-save
74 ;       push    r20     ;caller-save
75 ;       push    r21     ;caller-save
76 ;       push    r22     ;caller-save
77 ;       push    r23     ;caller-save
78 ;       push    r24     ;caller-save
79 ;       push    r25     ;caller-save
80 ;       push    r26     ;caller-save
81 ;       push    r27     ;caller-save
82         push    r28
83         push    r29
84 ;       push    r30     ;caller-save
85 ;       push    r31     ;caller-save
86
87         in      r18,SPL-__SFR_OFFSET    ; r18:r19 = SP
88         in      r19,SPH-__SFR_OFFSET
89         movw    r26,r22                 ; X = save_sp
90         st      X+,r18                  ; *save_sp = SP
91         st      X,r19
92         movw    r26,r24                 ; X = new_sp
93         ld      r18,X+
94         ld      r19,X
95
96 ;       Set new stack pointer.
97 ;       AVR is an 8 bit processor so
98 ;       care must be taken when updating
99 ;       SP that is a 16 bit reg.
100 ;       Two instructions are required to update SP
101 ;       so an IRQ can sneak in between them.
102 ;       So IRQ *MUST* be disabled and then restored.
103         cli                             ; Disable interrupt
104         out     SPL-__SFR_OFFSET,r18    ; SP = *new_sp
105         out     SPH-__SFR_OFFSET,r19
106         out     SREG-__SFR_OFFSET,r0    ; Restore previous IRQ state
107
108 ;       pop     r31     ;caller-save
109 ;       pop     r30     ;caller-save
110         pop     r29
111         pop     r28
112 ;       pop     r27     ;caller-save
113 ;       pop     r26     ;caller-save
114 ;       pop     r25     ;caller-save
115 ;       pop     r24     ;caller-save
116 ;       pop     r23     ;caller-save
117 ;       pop     r22     ;caller-save
118 ;       pop     r21     ;caller-save
119 ;       pop     r20     ;caller-save
120 ;       pop     r19     ;caller-save
121 ;       pop     r18     ;caller-save
122         pop     r17
123         pop     r16
124         pop     r15
125         pop     r14
126         pop     r13
127         pop     r12
128         pop     r11
129         pop     r10
130         pop     r9
131         pop     r8
132         pop     r7
133         pop     r6
134         pop     r5
135         pop     r4
136         pop     r3
137         pop     r2
138 ;       pop     r1      ;zero-reg
139         pop     r0
140         out     SREG-__SFR_OFFSET,r0
141
142         ret