1#include <barrelfish_kpi/registers_arch.h>
2
3.global disp_save_context
4
5/* Save the current thread's context.  This is only called for a voluntary
6 * switch, and is therefore reached via a function call.  This means that
7 * x0-x18 are expected to be clobbered, and will have been saved by the
8 * caller, if required.  We are passed the base of the save area in x0. */
9disp_save_context:
10    /* Save the callee-saved registers. */
11    stp x19, x20, [x0, #(19 * 8)]
12    stp x21, x22, [x0, #(21 * 8)]
13    stp x23, x24, [x0, #(23 * 8)]
14    stp x25, x26, [x0, #(25 * 8)]
15    stp x27, x28, [x0, #(27 * 8)]
16    stp x29, x30, [x0, #(29 * 8)]
17
18    /* Save the stack pointer, and the address of our return stub. */
19    mov x1, sp
20    adr x2, disp_save_context_resume
21    stp x1, x2, [x0, #(31 * 8)]
22
23    /* Skip SPSR - we can clobber it. */
24
25/* This code is executed in two different contexts: First, it's just the
26 * return to caller for disp_save_context.  Second, it's the return trampoline
27 * to resume a thread - this is the return address that we stash in the
28 * thread's trap frame, and it branches to whatever return address was saved
29 * alongside it. */
30disp_save_context_resume:
31    ret
32