Skip to content

Commit 6c1a9db

Browse files
jenswi-linaroAlex Shi
authored andcommitted
ARM: 8478/2: arm/arm64: add arm-smccc
Adds helpers to do SMC and HVC based on ARM SMC Calling Convention. CONFIG_HAVE_ARM_SMCCC is enabled for architectures that may support the SMC or HVC instruction. It's the responsibility of the caller to know if the SMC instruction is supported by the platform. This patch doesn't provide an implementation of the declared functions. Later patches will bring in implementations and set CONFIG_HAVE_ARM_SMCCC for ARM and ARM64 respectively. Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> (cherry picked from commit 98dd64f34f47ce19b388d9015f767f48393a81eb) Signed-off-by: Alex Shi <alex.shi@linaro.org>
1 parent 6ee496d commit 6c1a9db

2 files changed

Lines changed: 107 additions & 0 deletions

File tree

drivers/firmware/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ config QCOM_SCM_64
173173
def_bool y
174174
depends on QCOM_SCM && ARM64
175175

176+
config HAVE_ARM_SMCCC
177+
bool
178+
176179
source "drivers/firmware/broadcom/Kconfig"
177180
source "drivers/firmware/google/Kconfig"
178181
source "drivers/firmware/efi/Kconfig"

include/linux/arm-smccc.h

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright (c) 2015, Linaro Limited
3+
*
4+
* This software is licensed under the terms of the GNU General Public
5+
* License version 2, as published by the Free Software Foundation, and
6+
* may be copied, distributed, and modified under those terms.
7+
*
8+
* This program is distributed in the hope that it will be useful,
9+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* GNU General Public License for more details.
12+
*
13+
*/
14+
#ifndef __LINUX_ARM_SMCCC_H
15+
#define __LINUX_ARM_SMCCC_H
16+
17+
#include <linux/linkage.h>
18+
#include <linux/types.h>
19+
20+
/*
21+
* This file provides common defines for ARM SMC Calling Convention as
22+
* specified in
23+
* http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
24+
*/
25+
26+
#define ARM_SMCCC_STD_CALL 0
27+
#define ARM_SMCCC_FAST_CALL 1
28+
#define ARM_SMCCC_TYPE_SHIFT 31
29+
30+
#define ARM_SMCCC_SMC_32 0
31+
#define ARM_SMCCC_SMC_64 1
32+
#define ARM_SMCCC_CALL_CONV_SHIFT 30
33+
34+
#define ARM_SMCCC_OWNER_MASK 0x3F
35+
#define ARM_SMCCC_OWNER_SHIFT 24
36+
37+
#define ARM_SMCCC_FUNC_MASK 0xFFFF
38+
39+
#define ARM_SMCCC_IS_FAST_CALL(smc_val) \
40+
((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
41+
#define ARM_SMCCC_IS_64(smc_val) \
42+
((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
43+
#define ARM_SMCCC_FUNC_NUM(smc_val) ((smc_val) & ARM_SMCCC_FUNC_MASK)
44+
#define ARM_SMCCC_OWNER_NUM(smc_val) \
45+
(((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
46+
47+
#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
48+
(((type) << ARM_SMCCC_TYPE_SHIFT) | \
49+
((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
50+
(((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
51+
((func_num) & ARM_SMCCC_FUNC_MASK))
52+
53+
#define ARM_SMCCC_OWNER_ARCH 0
54+
#define ARM_SMCCC_OWNER_CPU 1
55+
#define ARM_SMCCC_OWNER_SIP 2
56+
#define ARM_SMCCC_OWNER_OEM 3
57+
#define ARM_SMCCC_OWNER_STANDARD 4
58+
#define ARM_SMCCC_OWNER_TRUSTED_APP 48
59+
#define ARM_SMCCC_OWNER_TRUSTED_APP_END 49
60+
#define ARM_SMCCC_OWNER_TRUSTED_OS 50
61+
#define ARM_SMCCC_OWNER_TRUSTED_OS_END 63
62+
63+
/**
64+
* struct arm_smccc_res - Result from SMC/HVC call
65+
* @a0-a3 result values from registers 0 to 3
66+
*/
67+
struct arm_smccc_res {
68+
unsigned long a0;
69+
unsigned long a1;
70+
unsigned long a2;
71+
unsigned long a3;
72+
};
73+
74+
/**
75+
* arm_smccc_smc() - make SMC calls
76+
* @a0-a7: arguments passed in registers 0 to 7
77+
* @res: result values from registers 0 to 3
78+
*
79+
* This function is used to make SMC calls following SMC Calling Convention.
80+
* The content of the supplied param are copied to registers 0 to 7 prior
81+
* to the SMC instruction. The return values are updated with the content
82+
* from register 0 to 3 on return from the SMC instruction.
83+
*/
84+
asmlinkage void arm_smccc_smc(unsigned long a0, unsigned long a1,
85+
unsigned long a2, unsigned long a3, unsigned long a4,
86+
unsigned long a5, unsigned long a6, unsigned long a7,
87+
struct arm_smccc_res *res);
88+
89+
/**
90+
* arm_smccc_hvc() - make HVC calls
91+
* @a0-a7: arguments passed in registers 0 to 7
92+
* @res: result values from registers 0 to 3
93+
*
94+
* This function is used to make HVC calls following SMC Calling
95+
* Convention. The content of the supplied param are copied to registers 0
96+
* to 7 prior to the HVC instruction. The return values are updated with
97+
* the content from register 0 to 3 on return from the HVC instruction.
98+
*/
99+
asmlinkage void arm_smccc_hvc(unsigned long a0, unsigned long a1,
100+
unsigned long a2, unsigned long a3, unsigned long a4,
101+
unsigned long a5, unsigned long a6, unsigned long a7,
102+
struct arm_smccc_res *res);
103+
104+
#endif /*__LINUX_ARM_SMCCC_H*/

0 commit comments

Comments
 (0)