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.
9 * \brief AVR context switch
13 * \author Bernardo Innocenti <bernie@develer.com>
14 * \author Stefano Fedrigo <aleph@develer.com>
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().
25 /* void asm_switch_context(void **new_sp, void **save_sp) */
26 .globl asm_switch_context
29 ; r0 is the TEMP REG and can be used freely.
30 ; r1 is the ZERO REG and must always contain 0.
32 ; Stack frame is 19 byte, remember to update
33 ; CPU_SAVED_REGS_CNT if you change pushed regs.
35 in r0,SREG-__SFR_OFFSET
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
66 ; push r30 ;caller-save
67 ; push r31 ;caller-save
69 ; First parameter (new_sp) is in r24:r25, second (save_sp) in r22:r23
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
76 movw r26,r24 ; X = new_sp
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
92 ; pop r31 ;caller-save
93 ; pop r30 ;caller-save
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
124 out SREG-__SFR_OFFSET,r0
129 /* int asm_switch_version(void) */
130 .globl asm_switch_version