mirror of https://github.com/zrafa/xinu-avr.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
2.8 KiB
130 lines
2.8 KiB
/* |
|
* ctxsw.S - ctxsw |
|
* avr-Xinu |
|
* |
|
* Created by Michael Minor on 12/7/08. |
|
* Copyright 2010. All rights reserved. |
|
* |
|
*/ |
|
|
|
|
|
/*----------------------------------------------------------------------------------------*/ |
|
/* ctxsw -- actually perform context switch, saving and loading registers */ |
|
/*----------------------------------------------------------------------------------------*/ |
|
|
|
|
|
; void ctxsw(char *old_pregs, char *new_pregs); |
|
; The stack contains the return address upon entry to this routine, and |
|
; |
|
; R25 => address of save area with OLD registers + PS |
|
; R24 => address of save area (low) |
|
; R23 => address of save area with NEW registers + PS |
|
; R22 => address of save area (low byte) |
|
; |
|
; |
|
; The saved state consists of the values of R0-R31 upon entry, SP_L, SP_H, |
|
; PC_L, PC_H, equal to the return address, and the PS (SREG) |
|
; |
|
; Save image: r0,r1,r2,r3,r4,r5,r6,...,r26,r27,r28,r29,r30,r31,SP_L,SP_H,PC_L,PC_H,SREG,0x00 |
|
; 0 1 2 3 4 5 6 ... 26 27 28 29 30 31 32 33 34 35 36, 37 |
|
|
|
|
|
|
|
.set __SREG__,0x3f ; Status register |
|
.set __SP_H__,0x3e ; Stack pointer high |
|
.set __SP_L__,0x3d ; Stack pointer low |
|
.global ctxsw |
|
|
|
ctxsw: |
|
push r31 |
|
push r30 |
|
movw r30,r24 ; get first argument |
|
std Z+0,r0 ; save r0 |
|
in r0,__SREG__ ; get SREG |
|
cli ; disable interrupts |
|
std Z+36,r0 ; save SREG |
|
std Z+1,r1 ; save r1 |
|
std Z+2,r2 ; save r2 |
|
std Z+3,r3 |
|
std Z+4,r4 |
|
std Z+5,r5 |
|
std Z+6,r6 |
|
std Z+7,r7 |
|
std Z+8,r8 |
|
std Z+9,r9 |
|
std Z+10,r10 ; ... |
|
std Z+11,r11 |
|
std Z+12,r12 |
|
std Z+13,r13 |
|
std Z+14,r14 |
|
std Z+15,r15 |
|
std Z+16,r16 |
|
std Z+17,r17 |
|
std Z+18,r18 |
|
std Z+19,r19 |
|
std Z+20,r20 |
|
std Z+21,r21 |
|
std Z+22,r22 |
|
std Z+23,r23 |
|
std Z+24,r24 |
|
std Z+25,r25 |
|
std Z+26,r26 |
|
std Z+27,r27 |
|
std Z+28,r28 ; save r28 |
|
std Z+29,r29 ; save r29 |
|
pop r0 ; get saved r30 |
|
std Z+30,r0 ; save r30 |
|
pop r0 ; get saved r31 |
|
std Z+31,r0 ; save r31 |
|
in r0,__SP_L__ ; get SP_L |
|
std Z+32,r0 ; save |
|
in r0,__SP_H__ ; get SP_H |
|
std Z+33,r0 ; save |
|
|
|
movw r30,r22 ; get address of new process save area |
|
ldd r0,Z+32 ; get SP_L |
|
out __SP_L__,r0 ; load new SP -- SWITCH STACKS |
|
ldd r0,Z+33 |
|
out __SP_H__,r0 |
|
|
|
ldd r0,Z+31 ; get saved r31 |
|
push r0 ; save r31 |
|
ldd r0,Z+30 ; get saved r30 |
|
push r0 ; save r30 |
|
ldd r29,Z+29 ; load r29 |
|
ldd r28,Z+28 ; load r28 |
|
ldd r27,Z+27 ; ... |
|
ldd r26,Z+26 |
|
ldd r25,Z+25 |
|
ldd r24,Z+24 |
|
ldd r23,Z+23 |
|
ldd r22,Z+22 |
|
ldd r21,Z+21 |
|
ldd r20,Z+20 |
|
ldd r19,Z+19 |
|
ldd r18,Z+18 |
|
ldd r17,Z+17 |
|
ldd r16,Z+16 |
|
ldd r15,Z+15 |
|
ldd r14,Z+14 |
|
ldd r13,Z+13 |
|
ldd r12,Z+12 |
|
ldd r11,Z+11 |
|
ldd r10,Z+10 |
|
ldd r9,Z+9 |
|
ldd r8,Z+8 |
|
ldd r7,Z+7 |
|
ldd r6,Z+6 |
|
ldd r5,Z+5 |
|
ldd r4,Z+4 |
|
ldd r3,Z+3 |
|
ldd r2,Z+2 ; ... |
|
ldd r1,Z+1 ; load r1 |
|
ldd r0,Z+36 ; get saved SREG |
|
out __SREG__,r0 ; restore SREG - may enable interrupts |
|
ldd r0,Z+0 ; load r0 |
|
pop r30 ; load r30 & r31 |
|
pop r31 |
|
ret ; load PC, and execute new process |
|
|
|
|
|
|