84fa14d3287af07337649412ce29d9a2e8bd3233
[bertos.git] / kern / switch_avr.S
1 /*!
2  * \file
3  * <!--
4  * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
5  * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
6  * This file is part of DevLib - See devlib/README for information.
7  * -->
8  *
9  * \brief AVR context switch
10  *
11  * \version $Id$
12  *
13  * \author Bernardo Innocenti <bernie@develer.com>
14  * \author Stefano Fedrigo <aleph@develer.com>
15  */
16
17 #include <avr/io.h>
18
19 /*
20  * NOTE: At each change of this function affecting proc.c
21  * (i.e. arguments, data stored in the stack) bump up version
22  * number in asm_switch_version().
23  */
24
25 /* void asm_switch_context(void **new_sp, void **save_sp) */
26 .globl asm_switch_context
27 asm_switch_context:
28
29         in      r0,SREG-__SFR_OFFSET
30         push    r0
31 ;       push    r0      caller-save
32 ;       push    r1      caller-save
33         push    r2
34         push    r3
35         push    r4
36         push    r5
37         push    r6
38         push    r7
39         push    r8
40         push    r9
41         push    r10
42         push    r11
43         push    r12
44         push    r13
45         push    r14
46         push    r15
47         push    r16
48         push    r17
49 ;       push    r18     caller-save
50 ;       push    r19     caller-save
51 ;       push    r20     caller-save
52 ;       push    r21     caller-save
53 ;       push    r22     caller-save
54 ;       push    r23     caller-save
55 ;       push    r24     caller-save
56 ;       push    r25     caller-save
57 ;       push    r26     caller-save
58 ;       push    r27     caller-save
59         push    r28
60         push    r29
61 ;       push    r30     caller-save
62 ;       push    r31     caller-save
63
64 ; First parameter (new_sp) is in r24:r25, second (save_sp) in r22:r23
65
66         in      r0,SPL-__SFR_OFFSET     ; r0:r1 = SP
67         in      r1,SPH-__SFR_OFFSET
68         movw    r26,r22                 ; X = save_sp
69         st      X+,r0                   ; *save_sp = SP
70         st      X,r1
71         movw    r26,r24                 ; X = new_sp
72         ld      r0,X+
73         ld      r1,X
74         out     SPL-__SFR_OFFSET,r0     ; SP = *new_sp
75         out     SPH-__SFR_OFFSET,r1
76
77 ;       pop     r31     caller-save
78 ;       pop     r30     caller-save
79         pop     r29
80         pop     r28
81 ;       pop     r27     caller-save
82 ;       pop     r26     caller-save
83 ;       pop     r25     caller-save
84 ;       pop     r24     caller-save
85 ;       pop     r23     caller-save
86 ;       pop     r22     caller-save
87 ;       pop     r21     caller-save
88 ;       pop     r20     caller-save
89 ;       pop     r19     caller-save
90 ;       pop     r18     caller-save
91         pop     r17
92         pop     r16
93         pop     r15
94         pop     r14
95         pop     r13
96         pop     r12
97         pop     r11
98         pop     r10
99         pop     r9
100         pop     r8
101         pop     r7
102         pop     r6
103         pop     r5
104         pop     r4
105         pop     r3
106         pop     r2
107 ;       pop     r1      caller-save
108 ;       pop     r0      caller-save
109         pop     r0
110         out     SREG-__SFR_OFFSET,r0
111
112         ret
113
114
115 /* int asm_switch_version(void) */
116 .globl asm_switch_version
117 asm_switch_version:
118         ldi r24,lo8(1)
119         ldi r25,hi8(1)
120         ret
121