1// Copyright 2018 The Fuchsia Authors
2//
3// Use of this source code is governed by a MIT-style
4// license that can be found in the LICENSE file or at
5// https://opensource.org/licenses/MIT
6
7#include <asm.h>
8#include <arch/asm_macros.h>
9
10// The ARM SMCCC v1.0 calling convention provides the following guarantees about registers:
11//
12//  Register     Modified    Return State
13//  X0...X3      Yes         Result values
14//  X4...X17     Yes         Unpredictable
15//  X18...X30    No          Preserved
16//  SP_EL0       No          Preserved
17//  SP_ELx       No          Preserved
18//
19
20// The arm_smccc_smc/hvc functions are almost direct calls to EL3/EL2. The AAPCS64 places the
21// function parameters in x0-x7, which matches the SMCCC input parameters. The return value type
22// is greater than 16 bytes, so the indirect result location register (x8) must be used to
23// populate the result. Since this register is not preserved across the SMC call, it must be
24// stored on the stack. For the purposes of AAPCS64 compatibility, the frame pointer (x29) is
25// also stored on the stack.
26
27// arm_smccc_result_t arm_smccc_smc(uint32_t w0, uint64_t x1, uint64_t x2, uint64_t x3,
28//                                  uint64_t x4, uint64_t x5, uint64_t x6, uint32_t w7);
29FUNCTION(arm_smccc_smc)
30    push_regs x8, x29
31    smc       #0
32    pop_regs  x8, x29
33    stp       x0, x1, [x8]
34    stp       x2, x3, [x8, #16]
35    ret
36END_FUNCTION(arm_smccc_smc)
37
38// arm_smccc_result_t arm_smccc_hvc(uint32_t w0, uint64_t x1, uint64_t x2, uint64_t x3,
39//                                  uint64_t x4, uint64_t x5, uint64_t x6, uint32_t w7);
40FUNCTION(arm_smccc_hvc)
41    push_regs x8, x29
42    hvc       #0
43    pop_regs  x8, x29
44    stp       x0, x1, [x8]
45    stp       x2, x3, [x8, #16]
46    ret
47END_FUNCTION(arm_smccc_hvc)
48
49