#include <config.h>
#include <model/statedata.h>
#include <arch/fastpath/fastpath.h>
#include <arch/kernel/traps.h>
#include <api/syscall.h>
#include <arch/linker.h>
#include <machine/fpu.h>
#include <benchmark/benchmark_track.h>
#include <benchmark/benchmark_utilisation.h>
void VISIBLE NORETURN restore_user_context(void)
{
NODE_UNLOCK_IF_HELD;
c_exit_hook();
#ifdef CONFIG_HAVE_FPU
lazyFPURestore(ksCurThread);
#endif
writeTPIDRURW(getRegister(ksCurThread, TPIDRURW));
asm volatile(
"mov sp, %0 \n"
"ldp x21, x22, [sp, %[SP_EL0]] \n"
"ldr x23, [sp, %[SPSR_EL1]] \n"
"msr sp_el0, x21 \n"
"msr elr_el1, x22 \n"
"msr spsr_el1, x23 \n"
"ldp x0, x1, [sp, #16 * 0] \n"
"ldp x2, x3, [sp, #16 * 1] \n"
"ldp x4, x5, [sp, #16 * 2] \n"
"ldp x6, x7, [sp, #16 * 3] \n"
"ldp x8, x9, [sp, #16 * 4] \n"
"ldp x10, x11, [sp, #16 * 5] \n"
"ldp x12, x13, [sp, #16 * 6] \n"
"ldp x14, x15, [sp, #16 * 7] \n"
"ldp x16, x17, [sp, #16 * 8] \n"
"ldp x18, x19, [sp, #16 * 9] \n"
"ldp x20, x21, [sp, #16 * 10] \n"
"ldp x22, x23, [sp, #16 * 11] \n"
"ldp x24, x25, [sp, #16 * 12] \n"
"ldp x26, x27, [sp, #16 * 13] \n"
"ldp x28, x29, [sp, #16 * 14] \n"
"ldr x30, [sp, %[LR]] \n"
"eret"
:
: "r" (ksCurThread->tcbArch.tcbContext.registers),
[SP_EL0] "i" (PT_SP_EL0), [SPSR_EL1] "i" (PT_SPSR_EL1), [LR] "i" (PT_LR)
: "memory"
);
UNREACHABLE();
}