blob: 31b3711bed7e6ae10294c5d897964ce65813980b [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/arch/asm.h>
// This system call is not yet in the stable vdso.
.weak zx_restricted_enter
.function restricted_exit, global
// Back from restricted mode
// x0 holds the context, which is the stack pointer
// x1 holds the reason code
// Restore the stack pointer at the point of the restricted enter wrapper.
mov sp,x0
// Restore the FPU register pointer
ldr x0, [sp, #16*6 + 8]
// Save the FPU register state if we were provided a non-null FPU register pointer
cbz x0, .after_store_fpu_registers
bl store_fpu_registers
.after_store_fpu_registers:
// Load the frame pointer and return address from the wrapper.
.epilogue.fp
// Restore the callee saved regs
ldp x28, x27, [sp, #16*0]
.cfi_adjust_cfa_offset -16
.cfi_same_value x28
.cfi_same_value x27
ldp x26, x25, [sp, #16*1]
.cfi_adjust_cfa_offset -16
.cfi_same_value x26
.cfi_same_value x25
ldp x24, x23, [sp, #16*2]
.cfi_adjust_cfa_offset -16
.cfi_same_value x24
.cfi_same_value x23
ldp x22, x21, [sp, #16*3]
.cfi_adjust_cfa_offset -16
.cfi_same_value x22
.cfi_same_value x21
ldp x20, x19, [sp, #16*4]
.cfi_adjust_cfa_offset -16
.cfi_same_value x20
.cfi_same_value x19
// Restore the reason code pointer and shadow call stack pointer from the stack.
ldp x2, x18, [sp, #16*5]
.cfi_adjust_cfa_offset -16
.cfi_same_value x18
.cfi_same_value x2
// Pop off all the now-restored state.
add sp, sp, #16*7
// Return the reason code from this function by setting the reason code pointer.
str x1, [x2]
// Return back to whatever the address was in the link register.
// Make it appear as if the wrapper had returned ZX_OK
mov x0, xzr
ret
.end_function
.function restricted_enter_wrapper, global
// Args 0 - 1 are already in place in X0 and X1.
// Make space on the stack for the 14 registers saved below.
sub sp, sp, #16*7
// Save pointer to the FPU register state and x0
stp x0, x3, [sp, #16*6]
.cfi_adjust_cfa_offset 16
.cfi_rel_offset x0, 0
.cfi_rel_offset x3, 8
// Save the reason code pointer and shadow call stack pointer on the stack.
stp x2, x18, [sp, #16*5]
.cfi_adjust_cfa_offset 16
.cfi_rel_offset x2, 0
.cfi_rel_offset x18, 8
// Save the callee saved regs since the return from restricted mode
// will modify all registers.
stp x20, x19, [sp, #16*4]
.cfi_adjust_cfa_offset 16
.cfi_rel_offset x20, 0
.cfi_rel_offset x19, 8
stp x22, x21, [sp, #16*3]
.cfi_adjust_cfa_offset 16
.cfi_rel_offset x22, 0
.cfi_rel_offset x21, 8
stp x24, x23, [sp, #16*2]
.cfi_adjust_cfa_offset 16
.cfi_rel_offset x24, 0
.cfi_rel_offset x23, 8
stp x26, x25, [sp, #16*1]
.cfi_adjust_cfa_offset 16
.cfi_rel_offset x26, 0
.cfi_rel_offset x25, 8
stp x28, x27, [sp, #16*0]
.cfi_adjust_cfa_offset 16
.cfi_rel_offset x28, 0
.cfi_rel_offset x27, 8
.prologue.fp
// If requested, load FPU register state from [x3]
cbz x3, .after_load_fpu_registers
mov x0, x3
bl load_fpu_registers
// Restore original x0
ldr x0, [sp, #16*7]
.after_load_fpu_registers:
// Pass the stack pointer as the context argument to the syscall.
mov x2, sp
bl zx_restricted_enter@PLT
// if we got here it must have failed
// Restore the registers that we saved so we can return to the caller.
// Restore the frame pointer and return address from the stack.
.epilogue.fp
// Restore the callee saved regs
ldp x28, x27, [sp, #16*0]
.cfi_adjust_cfa_offset -16
.cfi_same_value x28
.cfi_same_value x27
ldp x26, x25, [sp, #16*1]
.cfi_adjust_cfa_offset -16
.cfi_same_value x26
.cfi_same_value x25
ldp x24, x23, [sp, #16*2]
.cfi_adjust_cfa_offset -16
.cfi_same_value x24
.cfi_same_value x23
ldp x22, x21, [sp, #16*3]
.cfi_adjust_cfa_offset -16
.cfi_same_value x22
.cfi_same_value x21
ldp x20, x19, [sp, #16*4]
.cfi_adjust_cfa_offset -16
.cfi_same_value x20
.cfi_same_value x19
// Restore the reason code pointer and shadow call stack pointer from the stack.
ldp x2, x18, [sp, #16*5]
.cfi_adjust_cfa_offset -16
.cfi_same_value x18
.cfi_same_value x2
// Pop all the callee saved registers off the stack.
add sp, sp, #16*7
ret
.end_function
// Load the contents of the array in *x0 to the FPU.
.function load_fpu_registers, global
ldp q0, q1, [x0]
ldp q2, q3, [x0, #32]
ldp q4, q5, [x0, #64]
ldp q6, q7, [x0, #96]
ldp q8, q9, [x0, #128]
ldp q10, q11, [x0, #160]
ldp q12, q13, [x0, #192]
ldp q14, q15, [x0, #224]
ldp q16, q17, [x0, #256]
ldp q18, q19, [x0, #288]
ldp q20, q21, [x0, #320]
ldp q22, q23, [x0, #352]
ldp q24, q25, [x0, #384]
ldp q26, q27, [x0, #416]
ldp q28, q29, [x0, #448]
ldp q30, q31, [x0, #480]
ret
.end_function
// Store the contents of the FPU into the array in *x0.
.function store_fpu_registers, global
stp q0, q1, [x0]
stp q2, q3, [x0, #32]
stp q4, q5, [x0, #64]
stp q6, q7, [x0, #96]
stp q8, q9, [x0, #128]
stp q10, q11, [x0, #160]
stp q12, q13, [x0, #192]
stp q14, q15, [x0, #224]
stp q16, q17, [x0, #256]
stp q18, q19, [x0, #288]
stp q20, q21, [x0, #320]
stp q22, q23, [x0, #352]
stp q24, q25, [x0, #384]
stp q26, q27, [x0, #416]
stp q28, q29, [x0, #448]
stp q30, q31, [x0, #480]
ret
.end_function