1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 * See "LICENSE_GPLv2.txt" for details. 9 * 10 * @TAG(DATA61_GPL) 11 */ 12 13#include <config.h> 14#include <model/statedata.h> 15#include <arch/fastpath/fastpath.h> 16#include <arch/kernel/traps.h> 17#include <api/syscall.h> 18#include <linker.h> 19#include <machine/fpu.h> 20 21#include <benchmark/benchmark_track.h> 22#include <benchmark/benchmark_utilisation.h> 23 24/** DONT_TRANSLATE */ 25void VISIBLE NORETURN restore_user_context(void) 26{ 27 NODE_UNLOCK_IF_HELD; 28 29 c_exit_hook(); 30 31#ifdef CONFIG_HAVE_FPU 32 lazyFPURestore(NODE_STATE(ksCurThread)); 33#endif /* CONFIG_HAVE_FPU */ 34 35 writeTPIDRURW(getRegister(NODE_STATE(ksCurThread), TPIDRURW)); 36 37 asm volatile( 38 "mov sp, %0 \n" 39 40 /* Restore thread's SPSR, LR, and SP */ 41 "ldp x21, x22, [sp, %[SP_EL0]] \n" 42 "ldr x23, [sp, %[SPSR_EL1]] \n" 43 "msr sp_el0, x21 \n" 44#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT 45 "msr elr_el2, x22 \n" 46 "msr spsr_el2, x23 \n" 47#else 48 "msr elr_el1, x22 \n" 49 "msr spsr_el1, x23 \n" 50#endif 51 /* Restore remaining registers */ 52 "ldp x0, x1, [sp, #16 * 0] \n" 53 "ldp x2, x3, [sp, #16 * 1] \n" 54 "ldp x4, x5, [sp, #16 * 2] \n" 55 "ldp x6, x7, [sp, #16 * 3] \n" 56 "ldp x8, x9, [sp, #16 * 4] \n" 57 "ldp x10, x11, [sp, #16 * 5] \n" 58 "ldp x12, x13, [sp, #16 * 6] \n" 59 "ldp x14, x15, [sp, #16 * 7] \n" 60 "ldp x16, x17, [sp, #16 * 8] \n" 61 "ldp x18, x19, [sp, #16 * 9] \n" 62 "ldp x20, x21, [sp, #16 * 10] \n" 63 "ldp x22, x23, [sp, #16 * 11] \n" 64 "ldp x24, x25, [sp, #16 * 12] \n" 65 "ldp x26, x27, [sp, #16 * 13] \n" 66 "ldp x28, x29, [sp, #16 * 14] \n" 67 "ldr x30, [sp, %[LR]] \n" 68 "eret" 69 : 70 : "r" (NODE_STATE(ksCurThread)->tcbArch.tcbContext.registers), 71 [SP_EL0] "i" (PT_SP_EL0), [SPSR_EL1] "i" (PT_SPSR_EL1), [LR] "i" (PT_LR) 72 : "memory" 73 ); 74 UNREACHABLE(); 75} 76