#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 <benchmark/benchmark_track.h>
#include <benchmark/benchmark_utilisation.h>
void VISIBLE NORETURN restore_user_context(void)
{
NODE_UNLOCK_IF_HELD;
word_t cur_thread_reg = (word_t) NODE_STATE(ksCurThread);
c_exit_hook();
#ifdef CONFIG_HARDWARE_DEBUG_API
restore_user_debug_context(NODE_STATE(ksCurThread));
#endif
#ifndef CONFIG_ARCH_ARM_V6
writeTPIDRURW(getRegister(NODE_STATE(ksCurThread), TPIDRURW));
#endif
if (config_set(CONFIG_ARM_HYPERVISOR_SUPPORT)) {
asm volatile(
"mov sp, %[cur_thread_reg] \n"
"pop {r0-r12} \n"
"pop {lr} \n"
"msr sp_usr, lr \n"
"ldr lr, [sp, #4] \n"
"msr elr_hyp, lr \n"
"ldr lr, [sp, #8] \n"
"msr spsr_hyp, lr \n"
"pop {lr} \n"
"eret"
:
: [cur_thread_reg] "r" (cur_thread_reg)
: "memory"
);
} else {
asm volatile("mov sp, %[cur_thread] \n\
ldmdb sp, {r0-lr}^ \n\
rfeia sp"
:
: [cur_thread] "r" (cur_thread_reg + LR_svc * sizeof(word_t))
);
}
UNREACHABLE();
}