1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright (c) 2015, Linaro Limited 4 */ 5 #include <linux/linkage.h> 6 #include <linux/arm-smccc.h> 7 8 #include <asm/asm-offsets.h> 9 #include <asm/assembler.h> 10 11 .macro SMCCC instr 12 \instr #0 13 ldr x4, [sp] 14 stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS] 15 stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS] 16 ldr x4, [sp, #8] 17 cbz x4, 1f /* no quirk structure */ 18 ldr x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS] 19 cmp x9, #ARM_SMCCC_QUIRK_QCOM_A6 20 b.ne 1f 21 str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS] 22 1: ret 23 .endm 24 25 /* 26 * void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, 27 * unsigned long a3, unsigned long a4, unsigned long a5, 28 * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, 29 * struct arm_smccc_quirk *quirk) 30 */ 31 SYM_FUNC_START(__arm_smccc_smc) 32 SMCCC smc 33 SYM_FUNC_END(__arm_smccc_smc) 34 EXPORT_SYMBOL(__arm_smccc_smc) 35 36 /* 37 * void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, 38 * unsigned long a3, unsigned long a4, unsigned long a5, 39 * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, 40 * struct arm_smccc_quirk *quirk) 41 */ 42 SYM_FUNC_START(__arm_smccc_hvc) 43 SMCCC hvc 44 SYM_FUNC_END(__arm_smccc_hvc) 45 EXPORT_SYMBOL(__arm_smccc_hvc) 46 47 .macro SMCCC_1_2 instr 48 /* Save `res` and free a GPR that won't be clobbered */ 49 stp x1, x19, [sp, #-16]! 50 51 /* Ensure `args` won't be clobbered while loading regs in next step */ 52 mov x19, x0 53 54 /* Load the registers x0 - x17 from the struct arm_smccc_1_2_regs */ 55 ldp x0, x1, [x19, #ARM_SMCCC_1_2_REGS_X0_OFFS] 56 ldp x2, x3, [x19, #ARM_SMCCC_1_2_REGS_X2_OFFS] 57 ldp x4, x5, [x19, #ARM_SMCCC_1_2_REGS_X4_OFFS] 58 ldp x6, x7, [x19, #ARM_SMCCC_1_2_REGS_X6_OFFS] 59 ldp x8, x9, [x19, #ARM_SMCCC_1_2_REGS_X8_OFFS] 60 ldp x10, x11, [x19, #ARM_SMCCC_1_2_REGS_X10_OFFS] 61 ldp x12, x13, [x19, #ARM_SMCCC_1_2_REGS_X12_OFFS] 62 ldp x14, x15, [x19, #ARM_SMCCC_1_2_REGS_X14_OFFS] 63 ldp x16, x17, [x19, #ARM_SMCCC_1_2_REGS_X16_OFFS] 64 65 \instr #0 66 67 /* Load the `res` from the stack */ 68 ldr x19, [sp] 69 70 /* Store the registers x0 - x17 into the result structure */ 71 stp x0, x1, [x19, #ARM_SMCCC_1_2_REGS_X0_OFFS] 72 stp x2, x3, [x19, #ARM_SMCCC_1_2_REGS_X2_OFFS] 73 stp x4, x5, [x19, #ARM_SMCCC_1_2_REGS_X4_OFFS] 74 stp x6, x7, [x19, #ARM_SMCCC_1_2_REGS_X6_OFFS] 75 stp x8, x9, [x19, #ARM_SMCCC_1_2_REGS_X8_OFFS] 76 stp x10, x11, [x19, #ARM_SMCCC_1_2_REGS_X10_OFFS] 77 stp x12, x13, [x19, #ARM_SMCCC_1_2_REGS_X12_OFFS] 78 stp x14, x15, [x19, #ARM_SMCCC_1_2_REGS_X14_OFFS] 79 stp x16, x17, [x19, #ARM_SMCCC_1_2_REGS_X16_OFFS] 80 81 /* Restore original x19 */ 82 ldp xzr, x19, [sp], #16 83 ret 84 .endm 85 86 /* 87 * void arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args, 88 * struct arm_smccc_1_2_regs *res); 89 */ 90 SYM_FUNC_START(arm_smccc_1_2_hvc) 91 SMCCC_1_2 hvc 92 SYM_FUNC_END(arm_smccc_1_2_hvc) 93 EXPORT_SYMBOL(arm_smccc_1_2_hvc) 94 95 /* 96 * void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args, 97 * struct arm_smccc_1_2_regs *res); 98 */ 99 SYM_FUNC_START(arm_smccc_1_2_smc) 100 SMCCC_1_2 smc 101 SYM_FUNC_END(arm_smccc_1_2_smc) 102 EXPORT_SYMBOL(arm_smccc_1_2_smc)
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.