--- xinu/sys/ctxsw.s 2018/04/24 17:39:02 1.1.1.1 +++ xinu/sys/ctxsw.s 2018/04/24 17:39:21 1.1.1.2 @@ -1,35 +1,44 @@ -/* ctxsw.s - ctxsw */ +|* ctxsw.s - ctxsw -#include +|*----------------------------------------------------------------------------- +|* ctxsw -- actually perform context switch, saving and loading registers +|* This routine is executed in kernel mode. +|* +|* Upon entry, d0-d7, a0-a6, the ssp, the sr, and the pc are +|* saved. The usp is ignored. +|* +|* Upon exit, all registers saved are restored, and the value +|* of the supervisor stack pointer is copied into the user +|* stack pointer. +|*----------------------------------------------------------------------------- -/*------------------------------------------------------------------------ - * ctxsw -- actually perform context switch, saving/loading registers - *------------------------------------------------------------------------ - * Upon entry to this routine, the current stack is assumed to be the kernel - * stack. The stack contains: - * - * AP+4 => address of save area with new registers, etc. - * Size of save area is PNREGS * sizeof (longword). - * - * Assumes interrupts are disabled. - * See proc.h for a description of the saved state (process control block). -*/ + .data .text - .align 1 /* location counter lowest bit is 0 */ - .globl _ctxsw /* declare the routine name global */ -_ctxsw: /* entry point to context switch */ - .word 0x0 /* entry mask -- save no registers */ - movpsl -(sp) /* push psl */ - pushal ctxswend /* push address at which old process */ - /* should resume when re-started */ - svpctx /* save old process' context in proctab */ - /* The values to save for PC & PSL are */ - /* popped off the kernel stack. */ - mtpr 4(ap), $PCBB /* move address of new process' save */ - /* area to Process Control Block Base */ - ldpctx /* load new process' context, push PSL */ - /* & PC on kernel stack. */ - rei /* start executing new process */ -ctxswend: - /* the OLD process returns here when resumed. */ - ret + .globl _ctxsw +_ctxsw: + movl a0, sp@- | Save A0 onto old stack + movl sp@(8), a0 | Move address of old area into A0 + moveml #0xffff,a0@ | Save all registers + movl sp@, a0@(32) | Put original A0 in old savearea + addql #8, a0@(60) | Move SP beyond return address + | as if a return has occured + addl #64, a0 | Skip past registers d0-7,a0-7 + movw #0, a0@+ | Pad SR savearea, since SR is a word + movw sr, a0@+ | Save SR in old savearea + movl sp@(4), a0@+ | Save PC in old savearea + +|Save image:d0,d1,d2,d3,d4,d5,d6,d7,a0,a1,a2,a3,a4,a5,a6,ssp,0x00, sr, pc +| 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 66 68 + + movl sp@(12),a0 | Move address of new area into A0 + moveml a0@,#0x7fff | Restore all regs (even A0) except SP + movl sp@(12),a0 | Move address of new area into A0 again + movl a0@(60),sp | Put SSP into both kernel stack + movl sp, usp | and user stack + movl a0@(68),sp@- | Move PC onto current stack + movw a0@(66),sp@- | Move SR onto current stack + movl a0@(32),a0 | Restore A0 from new area +| rte + movw sp@+,sr | (rte works differently on 68010) + rts | so do 68000-rte in effect this way + .data