David Howells | 803f691 | 2012-03-28 18:30:02 +0100 | [diff] [blame] | 1 | #ifndef _M68K_SWITCH_TO_H |
| 2 | #define _M68K_SWITCH_TO_H |
| 3 | |
| 4 | /* |
| 5 | * switch_to(n) should switch tasks to task ptr, first checking that |
| 6 | * ptr isn't the current task, in which case it does nothing. This |
| 7 | * also clears the TS-flag if the task we switched to has used the |
| 8 | * math co-processor latest. |
| 9 | */ |
| 10 | /* |
| 11 | * switch_to() saves the extra registers, that are not saved |
| 12 | * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and |
| 13 | * a0-a1. Some of these are used by schedule() and its predecessors |
| 14 | * and so we might get see unexpected behaviors when a task returns |
| 15 | * with unexpected register values. |
| 16 | * |
| 17 | * syscall stores these registers itself and none of them are used |
| 18 | * by syscall after the function in the syscall has been called. |
| 19 | * |
| 20 | * Beware that resume now expects *next to be in d1 and the offset of |
| 21 | * tss to be in a1. This saves a few instructions as we no longer have |
| 22 | * to push them onto the stack and read them back right after. |
| 23 | * |
| 24 | * 02/17/96 - Jes Sorensen (jds@kom.auc.dk) |
| 25 | * |
| 26 | * Changed 96/09/19 by Andreas Schwab |
| 27 | * pass prev in a0, next in a1 |
| 28 | */ |
| 29 | asmlinkage void resume(void); |
| 30 | #define switch_to(prev,next,last) do { \ |
| 31 | register void *_prev __asm__ ("a0") = (prev); \ |
| 32 | register void *_next __asm__ ("a1") = (next); \ |
| 33 | register void *_last __asm__ ("d1"); \ |
| 34 | __asm__ __volatile__("jbsr resume" \ |
| 35 | : "=a" (_prev), "=a" (_next), "=d" (_last) \ |
| 36 | : "0" (_prev), "1" (_next) \ |
| 37 | : "d0", "d2", "d3", "d4", "d5"); \ |
| 38 | (last) = _last; \ |
| 39 | } while (0) |
| 40 | |
| 41 | #endif /* _M68K_SWITCH_TO_H */ |