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